• XSS.stack #1 – первый литературный журнал от юзеров форума

Разные номера syscall в x64 и WOW64 на одной и той же системе

arsarsov

(L2) cache
Пользователь
Регистрация
07.08.2022
Сообщения
460
Реакции
272
В общем наглядно на скринах, по порядку
NtCreateProcess WOW64
1662649929604.png
NtCreateProcess x64
1662649977711.png
Тут все нормально, номера совпадают, идем далее
NtCreateThread WOW64
1662650059769.png
NtCreateThread x64
1662650118379.png
Тоже все нормально, совпадают
НО, теперь посмотрим на NtClose
1662650199070.png
1662650235707.png
Видим в одном случае 0x3000F и в другом просто 0xF
Что за фокусы ? Это явно не хук или что-то подобное, никаких прыжков нет, да и система нулевая, можно сказать только что установленная + и в памяти и в файле ситуация такая
И что самое интересное сходство как бы есть, младшие байты совпадают
 
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
Что за фокусы ? Это явно не хук или что-то подобное, никаких прыжков нет, да и система нулевая, можно сказать только что установленная + и в памяти и в файле ситуация такая
И что самое интересное сходство как бы есть, младшие байты совпадают
Это нормально, номер сискола 0x0F, там в 16 битах верхних в wow64 кодируется какая-то шняга, типа типов аргументов, чтобы их можно было конвертить в x64, или что-то такое, я уже не припомню сейчас.
 
О преобразование аргументов веселый челендж, а преобразование передаваемых структур туда и обратно еще веселее. Помни про выравнивание бро =)
 
О преобразование аргументов веселый челендж, а преобразование передаваемых структур туда и обратно еще веселее. Помни про выравнивание бро =)
Зачем их преобразовывать, перешел в режим x64 через Heaven`s Gate и работай как с исходными структурами x64, предполагается что вызываешь сискол уже со структурой собранной под x64 вариант
 
Зачем их преобразовывать, перешел в режим x64 через Heaven`s Gate и работай как с исходными структурами x64, предполагается что вызываешь сискол уже со структурой собранной под x64 вариант
Грустно было это читать.
но схематичненько

xxx MyZwSometihig(param1, ..., param10)
{
if use_syscalls
return syscall_MyZwSometihig(param1, ..., param10)
else:
return ntdll_MyZwSometihig(param1, ..., param10)
}


xxx syscall_MyZwSometihig(param1, ..., param10)
{
if wow64
конверт всего входящего 32бит в 64бит
go heavens gate
конверт всего полученного 64бит в 32бит
return converted

else
return go syscall

}

Для тех апи где нам нужно получать 64битные значения(например адреса) делаем вообще свои версии функций и они и в 32 и в 64 битах будут возвращать 64битные значения, там где нужно просто обрезаешь старшие 32 бит.
Без враперов апи тебя ждет грусть, особенно когда тебе понадобится делать сисколлы для множества апи, и если ты у тебя не будет конверсий ты утонешь в ифах.
 
Грустно было это читать.
но схематичненько

xxx MyZwSometihig(param1, ..., param10)
{
if use_syscalls
return syscall_MyZwSometihig(param1, ..., param10)
else:
return ntdll_MyZwSometihig(param1, ..., param10)
}


xxx syscall_MyZwSometihig(param1, ..., param10)
{
if wow64
конверт всего входящего 32бит в 64бит
go heavens gate
конверт всего полученного 64бит в 32бит
return converted

else
return go syscall

}

Для тех апи где нам нужно получать 64битные значения(например адреса) делаем вообще свои версии функций и они и в 32 и в 64 битах будут возвращать 64битные значения, там где нужно просто обрезаешь старшие 32 бит.
Без враперов апи тебя ждет грусть, особенно когда тебе понадобится делать сисколлы для множества апи, и если ты у тебя не будет конверсий ты утонешь в ифах.
Зачем ты все это расписываешь, у меня есть готовая рабочая реализация вызова сисколов под WoW64 в обход всех ntdll, я тебе написал что незачем вызывать функции в 32 битном варианте, это просто лишняя ненужная работа, что бы потом конвертить в 64, шелл который отрабатывает после гейта работает в x64 и проще сразу подавать ему на вход аргументы как это делается в обычном сисколе x64
 
Зачем ты все это расписываешь, у меня есть готовая рабочая реализация вызова сисколов под WoW64 в обход всех ntdll, я тебе написал что незачем вызывать функции в 32 битном варианте, это просто лишняя ненужная работа, что бы потом конвертить в 64, шелл который отрабатывает после гейта работает в x64 и проще сразу подавать ему на вход аргументы как это делается в обычном сисколе x64
Ты даже не понял о чем я, но да неважно. Молодец, так держать.
 
xxx syscall_MyZwSometihig(param1, ..., param10)
{
if wow64
конверт всего входящего 32бит в 64бит
go heavens gate
конверт всего полученного 64бит в 32бит
return converted

else
return go syscall

}
И да, если начинаем придираться, то из гейта потом нужно еще возвращатьсяобратно, так что надо бы добавить строку go_from_64onwow64_to_wow64
 
Ты даже не понял о чем я, но да неважно. Молодец, так держать.
Я тебя прекрасно понял, ты сначала делаешь проверку на то запущены ли мы в wow64 или система априори 32 бита и тогда можно делать sysenter без танцев с бубнами вроде гейтов
такие вещи подразумеваются, и данные проверки не сделает только начинающий системщик
 
Без враперов апи тебя ждет грусть, особенно когда тебе понадобится делать сисколлы для множества апи, и если ты у тебя не будет конверсий ты утонешь в ифах.
Не поверишь, но мой шелл универсален, принимает на вход ссылку на структуру, которая содержит всю нужную информацию, вроде номера системного вызова, количества параметров, ссылки на список параметров и так далее, далее шелл сам подготавливает регистры\стек к вызову и делает syscall, поэтому мне не нужно делать обертки, и тонуть в ифах не пришлось, там строк 50 на ассемблере, не больше
Зачем идти трудными путями если есть легкие, и к тому же универсальные
 
И да, если начинаем придираться, то из гейта потом нужно еще возвращатьсяобратно, так что надо бы добавить строку go_from_64onwow64_to_wow64
Не нужно. go_heavens_gate это считай функа которая иформирована что ей иполнить в 64бит режиме и что положить на стек, она переходит в 64 бит режим, подготавливает стек как ее информировали, вызывает адрес - например тот где сисколл, потом возвращается назад в вов64. А пост мой был про то где именно ты принимаешь решение использовать нтдлл, использовать сисколл, использовать сисколл только если в нативном режиме и тд тп, если у тебя без логика приложения про это знает то грусть.
 
go_heavens_gate это считай функа которая иформирована что ей иполнить в 64бит режиме и что положить на стек, она переходит в 64 бит режим, подготавливает стек как ее информировали, вызывает адрес - например тот где сисколл, потом возвращается назад в вов64.
Будем считать что отмазался, ну либо я не так понял, я привык разделять переход в гейт и выход из него, а так же сам код режима 64, потому что часто приходится морфить его, и это легче делать отдельно, так как движки у меня под 32 и 64 бита разные
А пост мой был про то где именно ты принимаешь решение использовать нтдлл, использовать сисколл, использовать сисколл только если в нативном режиме
я выше написал, такие проверки подразумеваются
 
Я тебе написал просто потому что мне когда то казалось что все что мне нужно это завести штук 5-10 апи в сисколл и этого хватит. Как я был наивен, и просто тебе подсказывал что если ты сейчас не подготовишся к тому что ты должен будешь дохренища всего переводить на сисколлы так что бы это все не размазывалось по биз логике приложения то ждет тебя тот еще перфоманс. Ну да ладно будем считать что решил выебнутся но у меня не вышло. Сорян короче, не буду мешать кодить супермалвару.
 
если ты сейчас не подготовишся к тому что ты должен будешь дохренища всего переводить на сисколлы так что бы это все не размазывалось по биз логике приложения то ждет тебя тот еще перфоманс
Я же написал уже выше, у меня шелл, который обрабатывает любые сисколы, независимо от количества, качества и прочих свойств параметров(аргументов)
Положил в структуру номер сискола, количество параметров; сами параметры идут непрерывным массивом в конце структуры; что бы описать новый сискол копируешь прототип нужной Nt функции, заменяешь количество аргументов и инициализацию аргументов в структуре, все, больше ничего не требуется что бы вызвать новый сискол, который у тебя еще не описан; снаружи это вызывается как обычная Nt функция из ntdll
1662667737681.png
 
До тебя не дошло что я хотел тебе сказать. Я скажем так сделал стойку на то что ты сказал что тебе ненужно конверитить переменные и структуры из 32 в 64 и обратно. Попбробую пояснить что я имел ввиду еще раз.

...
бизнес код приложения

SYSTEM_BASIC_INFORMATION basicInfo;

Get_SYSTEM_BASIC_INFORMATION(&basicInfo)
это бизнес код, он ожидает получить информацию и ему насрать wow64 он или нет, потому что бизнес код и он не вникает в детали а просто запрашивает что ему нужно, и потому что он биз код ему насрать как это будет исполнено, ему просто нужна инфа релевантная режиму, а режим у него 32бит

отметим что - SYSTEM_BASIC_INFORMATION разный для 32 и для 64бит
....

....
уровень взаимодействия с ос типа у нас тут фасад
bool Get_SYSTEM_BASIC_INFORMATION(PSYSTEM_BASIC_INFORMATION pBasicInfo)
{

NTSTATUS stat = wraper_ZwQuerySystemInformation(......бла бла бла)
}

....
уровень апи


NTSTATUS stat = wraper_ZwQuerySystemInformation(......бла бла бла)
{
if (Flag_we_must_use_syscall_everywhere){
if (SystemInformationClass == SystemBasicInformation){
поскольку для 32 и 64 бит структуры разные нам не похуй
if (mode_syswow64){
опа, структура которую мы получим от сисколла нам не подходит и мы ее из SYSTEM_BASIC_INFORMATION64 должны сконвертить в SYSTEM_BASIC_INFORMATION32 потому что от нас ожидают именно структуру SYSTEM_BASIC_INFORMATION32
}
else{
мы в нативно режиме и пох 32 это или 64
спокойно вызываем сисколл
}
}
}
else{
просто вызываем нтдлл потому что настройки не требуют от нас сисколлов
}
return status;
}

и в качестве жеста дружбы, мира, всякого хорошего список апи которые хукают
CsrClientConnectToServer
KiUserApcDispatcher


LdrLoadDll
LdrOpenImageFileOptionsKey
LdrUnloadDll


RegNtCallbackObjectContextCleanup
RegNtPostCreateKey
RegNtPostCreateKeyEx
RegNtPostDeleteKey
RegNtPostDeleteValueKey
RegNtPostEnumerateKey
RegNtPostEnumerateValueKey
RegNtPostFlushKey
RegNtPostKeyHandleClose
RegNtPostLoadKey
RegNtPostOpenKey
RegNtPostOpenKeyEx
RegNtPostQueryKey
RegNtPostQueryKeyName
RegNtPostQueryKeySecurity
RegNtPostQueryMultipleValueKey
RegNtPostQueryValueKey
RegNtPostRenameKey
RegNtPostReplaceKey
RegNtPostRestoreKey
RegNtPostSaveKey
RegNtPostSetInformationKey
RegNtPostSetKeySecurity
RegNtPostSetValueKey
RegNtPostUnLoadKey
RegNtPreCreateKey
RegNtPreCreateKeyEx
RegNtPreDeleteKey
RegNtPreDeleteValueKey
RegNtPreEnumerateKey
RegNtPreEnumerateValueKey
RegNtPreFlushKey
RegNtPreKeyHandleClose
RegNtPreLoadKey
RegNtPreOpenKey
RegNtPreOpenKeyEx
RegNtPreQueryKey
RegNtPreQueryKeyName
RegNtPreQueryKeySecurity
RegNtPreQueryMultipleValueKey
RegNtPreQueryValueKey
RegNtPreRenameKey
RegNtPreReplaceKey
RegNtPreRestoreKey
RegNtPreSaveKey
RegNtPreSetInformationKey
RegNtPreSetKeySecurity
RegNtPreSetValueKey
RegNtPreUnLoadKey


RtlAddVectoredExceptionHandler
RtlAllocateHeap
RtlCreateUserThread
RtlDecompressBuffer
RtlGetNativeSystemInformation
RtlInstallFunctionTableCallback
RtlWow64SetThreadContext


ZwAddBootEntry
ZwAdjustPrivilegesToken
ZwAlertResumeThread
ZwAllocateVirtualMemory
ZwAllocateVirtualMemoryEx
ZwAlpcConnectPort
ZwAlpcCreatePort
ZwAlpcSendWaitReceivePort
ZwClose
ZwCommitTransaction
ZwCreateEvent
ZwCreateFile
ZwCreateKey
ZwCreateMutant
ZwCreateProcess
ZwCreateProcessEx
ZwCreateSection
ZwCreateSectionEx
ZwCreateSemaphore
ZwCreateThread
ZwCreateThreadEx
ZwCreateTransaction
ZwCreateUserProcess
ZwDelayExecution
ZwDeleteBootEntry
ZwDeleteFile
ZwDeleteKey
ZwDeleteValueKey
ZwDeviceIoControlFile
ZwDuplicateObject
ZwFreeVirtualMemory
ZwGdiBitBlt
ZwGetContextThread
ZwLoadDriver
ZwMapUserPhysicalPages
ZwMapViewOfSection
ZwMapViewOfSectionEx
ZwModifyBootEntry
ZwOpenCreateFile
ZwOpenEvent
ZwOpenFile
ZwOpenKey
ZwOpenKeyEx
ZwOpenMutant
ZwOpenProcess
ZwOpenProcessToken
ZwOpenProcessTokenEx
ZwOpenSemaphore
ZwOpenThreadToken
ZwOpenThreadTokenEx
ZwProtectVirtualMemory
ZwQueryInformationProcess
ZwQueryInformationThread
ZwQueryInformationTokenTokenUser
ZwQuerySystemEnvironmentValueEx
ZwQuerySystemInformation
ZwQuerySystemInformationEx
ZwQuerySystemTime
ZwQueueApcThread
ZwQueueApcThreadEx
ZwQueueApcThreadEx2
ZwRaiseHardError
ZwReadVirtualMemory
ZwReleaseWorkerFactoryWorker
ZwRenameKey
ZwResumeProcess
ZwResumeThread
ZwRollbackTransaction
ZwSetContextThread
ZwSetInformationFile
ZwSetInformationProcess
ZwSetInformationProcessCriticalProcess
ZwSetInformationThread
ZwSetInformationThreadCriticalThread
ZwSetInformationThreadHideFromDebugger
ZwSetInformationThreadImpersonationToken
ZwSetInformationThreadWow64Context
ZwSetInformationTransaction
ZwSetInformationVirtualMemory
ZwSetSystemEnvironmentValueEx
ZwSetValueKey
ZwSuspendProcess
ZwSuspendThread
ZwSystemDebugControl
ZwTerminateProcess
ZwTerminateThread
ZwUnmapViewOfSection
ZwUnmapViewOfSectionEx
ZwUserGetAsyncKeyState
ZwUserGetClipboardData
ZwUserSetWindowsHookEx
ZwWriteFile
ZwWriteVirtualMemory

Когда то я думал что мне нужно просто вызвать сисколлом функи которые вернут хендлы и дальше с ними спокойно работать =)
Ты кстати вообще понимаешь что такое биз логика приложения и зачем леера? потому что писал именно про это. Всякое типа как сделать хевинс гейт, вызвать сисколл и прочая дребедень меня бы не зацепила писать тебе все это.
 
До тебя не дошло что я хотел тебе сказать. Я скажем так сделал стойку на то что ты сказал что тебе ненужно конверитить переменные и структуры из 32 в 64 и обратно. Попбробую пояснить что я имел ввиду еще раз.

...
бизнес код приложения

SYSTEM_BASIC_INFORMATION basicInfo;

Get_SYSTEM_BASIC_INFORMATION(&basicInfo)
это бизнес код, он ожидает получить информацию и ему насрать wow64 он или нет, потому что бизнес код и он не вникает в детали а просто запрашивает что ему нужно, и потому что он биз код ему насрать как это будет исполнено, ему просто нужна инфа релевантная режиму, а режим у него 32бит

отметим что - SYSTEM_BASIC_INFORMATION разный для 32 и для 64бит
....

....
уровень взаимодействия с ос типа у нас тут фасад
bool Get_SYSTEM_BASIC_INFORMATION(PSYSTEM_BASIC_INFORMATION pBasicInfo)
{

NTSTATUS stat = wraper_ZwQuerySystemInformation(......бла бла бла)
}

....
уровень апи


NTSTATUS stat = wraper_ZwQuerySystemInformation(......бла бла бла)
{
if (Flag_we_must_use_syscall_everywhere){
if (SystemInformationClass == SystemBasicInformation){
поскольку для 32 и 64 бит структуры разные нам не похуй
if (mode_syswow64){
опа, структура которую мы получим от сисколла нам не подходит и мы ее из SYSTEM_BASIC_INFORMATION64 должны сконвертить в SYSTEM_BASIC_INFORMATION32 потому что от нас ожидают именно структуру SYSTEM_BASIC_INFORMATION32
}
else{
мы в нативно режиме и пох 32 это или 64
спокойно вызываем сисколл
}
}
}
else{
просто вызываем нтдлл потому что настройки не требуют от нас сисколлов
}
return status;
}

и в качестве жеста дружбы, мира, всякого хорошего список апи которые хукают
CsrClientConnectToServer
KiUserApcDispatcher


LdrLoadDll
LdrOpenImageFileOptionsKey
LdrUnloadDll


RegNtCallbackObjectContextCleanup
RegNtPostCreateKey
RegNtPostCreateKeyEx
RegNtPostDeleteKey
RegNtPostDeleteValueKey
RegNtPostEnumerateKey
RegNtPostEnumerateValueKey
RegNtPostFlushKey
RegNtPostKeyHandleClose
RegNtPostLoadKey
RegNtPostOpenKey
RegNtPostOpenKeyEx
RegNtPostQueryKey
RegNtPostQueryKeyName
RegNtPostQueryKeySecurity
RegNtPostQueryMultipleValueKey
RegNtPostQueryValueKey
RegNtPostRenameKey
RegNtPostReplaceKey
RegNtPostRestoreKey
RegNtPostSaveKey
RegNtPostSetInformationKey
RegNtPostSetKeySecurity
RegNtPostSetValueKey
RegNtPostUnLoadKey
RegNtPreCreateKey
RegNtPreCreateKeyEx
RegNtPreDeleteKey
RegNtPreDeleteValueKey
RegNtPreEnumerateKey
RegNtPreEnumerateValueKey
RegNtPreFlushKey
RegNtPreKeyHandleClose
RegNtPreLoadKey
RegNtPreOpenKey
RegNtPreOpenKeyEx
RegNtPreQueryKey
RegNtPreQueryKeyName
RegNtPreQueryKeySecurity
RegNtPreQueryMultipleValueKey
RegNtPreQueryValueKey
RegNtPreRenameKey
RegNtPreReplaceKey
RegNtPreRestoreKey
RegNtPreSaveKey
RegNtPreSetInformationKey
RegNtPreSetKeySecurity
RegNtPreSetValueKey
RegNtPreUnLoadKey


RtlAddVectoredExceptionHandler
RtlAllocateHeap
RtlCreateUserThread
RtlDecompressBuffer
RtlGetNativeSystemInformation
RtlInstallFunctionTableCallback
RtlWow64SetThreadContext


ZwAddBootEntry
ZwAdjustPrivilegesToken
ZwAlertResumeThread
ZwAllocateVirtualMemory
ZwAllocateVirtualMemoryEx
ZwAlpcConnectPort
ZwAlpcCreatePort
ZwAlpcSendWaitReceivePort
ZwClose
ZwCommitTransaction
ZwCreateEvent
ZwCreateFile
ZwCreateKey
ZwCreateMutant
ZwCreateProcess
ZwCreateProcessEx
ZwCreateSection
ZwCreateSectionEx
ZwCreateSemaphore
ZwCreateThread
ZwCreateThreadEx
ZwCreateTransaction
ZwCreateUserProcess
ZwDelayExecution
ZwDeleteBootEntry
ZwDeleteFile
ZwDeleteKey
ZwDeleteValueKey
ZwDeviceIoControlFile
ZwDuplicateObject
ZwFreeVirtualMemory
ZwGdiBitBlt
ZwGetContextThread
ZwLoadDriver
ZwMapUserPhysicalPages
ZwMapViewOfSection
ZwMapViewOfSectionEx
ZwModifyBootEntry
ZwOpenCreateFile
ZwOpenEvent
ZwOpenFile
ZwOpenKey
ZwOpenKeyEx
ZwOpenMutant
ZwOpenProcess
ZwOpenProcessToken
ZwOpenProcessTokenEx
ZwOpenSemaphore
ZwOpenThreadToken
ZwOpenThreadTokenEx
ZwProtectVirtualMemory
ZwQueryInformationProcess
ZwQueryInformationThread
ZwQueryInformationTokenTokenUser
ZwQuerySystemEnvironmentValueEx
ZwQuerySystemInformation
ZwQuerySystemInformationEx
ZwQuerySystemTime
ZwQueueApcThread
ZwQueueApcThreadEx
ZwQueueApcThreadEx2
ZwRaiseHardError
ZwReadVirtualMemory
ZwReleaseWorkerFactoryWorker
ZwRenameKey
ZwResumeProcess
ZwResumeThread
ZwRollbackTransaction
ZwSetContextThread
ZwSetInformationFile
ZwSetInformationProcess
ZwSetInformationProcessCriticalProcess
ZwSetInformationThread
ZwSetInformationThreadCriticalThread
ZwSetInformationThreadHideFromDebugger
ZwSetInformationThreadImpersonationToken
ZwSetInformationThreadWow64Context
ZwSetInformationTransaction
ZwSetInformationVirtualMemory
ZwSetSystemEnvironmentValueEx
ZwSetValueKey
ZwSuspendProcess
ZwSuspendThread
ZwSystemDebugControl
ZwTerminateProcess
ZwTerminateThread
ZwUnmapViewOfSection
ZwUnmapViewOfSectionEx
ZwUserGetAsyncKeyState
ZwUserGetClipboardData
ZwUserSetWindowsHookEx
ZwWriteFile
ZwWriteVirtualMemory

Когда то я думал что мне нужно просто вызвать сисколлом функи которые вернут хендлы и дальше с ними спокойно работать =)
Ты кстати вообще понимаешь что такое биз логика приложения и зачем леера? потому что писал именно про это. Всякое типа как сделать хевинс гейт, вызвать сисколл и прочая дребедень меня бы не зацепила писать тебе все это.
Понимаешь, я пишу код сразу так, что бы его удобно было использовать в любых ситуациях, ты же описываешь решения, которые требуются что бы заставить работать условно чужой код, который был написан абы как с точки зрения вызовов сисколов
Если мне нужно дернуть сискол в WoW64, я СРАЗУ создаю структуры в формате 64 бит, мне незачем их конвертировать, и затем в коде WoW64 я беру эти значения из структуры по смещениям x64, если не учитывать разницу в смещениях, которая автоматически настраивается при обращениям к полям через struct->field, то единственная разница остается в размерах указателей, при этом это так же не проблема, потому что можно смело отсекать старшие 32 бита, потому что в симуляции WoW64 не существует адресов больше 0x7FFFFFFF c точки хрения самого кода WoW64
К тому же если учесть, что сама по себе технология Heavens Gate достаточно редкое явление в практике, и не используется обычными приложениями в "ручном режиме", то мне никогда не придется переделывать бизнес логику приложения, исходный код которого я взял где-то на стороне
Heavens Gate используется только в малваре 99,99%
А по поводу моего кода смотри самую первую строку этого сообщения до первой запятой, пиши сразу так что бы не пришлось переписывать
Все что я выше писал, все сообщения, только в контексте вызова сисколов в wow64, все, зачем ты сюда приплел бизнес логику и все остальное я не понимаю
Есть программа, 32 бит версия и 64 бит
В 64 бит классически дергаем сисколы по номерам без хевигейта
В 32 битах дергаем их через хевингейт если мы под WOW64 или точно так же напрямую если мы в системе 32 бита, участок кода который работает через хевингейт работает со структурами типа 64 бита, и все, больше ничего не надо конвертировать и придумывать, участок который работает с 32 бит системой работает со структурами 32 бита, все банально и просто, никаких конвертаций
 
Последнее редактирование:


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх