- 237
- 442
Будет очень хорошо, если вы знаете каплю asm, а точнее push, pop, call, ecx, соглашение вызовов. Если вы ничего не знаете из вышеперечисленного, то настало google-время.
Сразу запомним особенность, опкоды с наличием function в названии отличаются от аналогичных опкодов без function только тем, что мы указываем в конце переменную, в которую запишется результат функции, в остальном они одинаковые.
Мы будем учиться использовать cdecl/stdcall/thiscall.
Для примера возьмем:
_stdcall HMODULE WINAPI GetModuleHandle(LPCTSTR lpModuleName);
_cdecl void addDebugMessage(cSampChatInfo*, char* text, format...);
_thiscall void CDXUTDialog::SetBackgroundColors(DWORD clr1, DWORD clr2, DWORD clr3, DWORD clr4);
1)_stdcall HMODULE WINAPI GetModuleHandle(LPCTSTR lpModuleName)
_stdcall позволяет вызывать функции с заданным для неё количеством параметров.
Как выглядит в asm вызов GetModuleHandle(“samp.dll”):
Выглядит просто, да так оно и есть.
Для вызова stdcall используются 0AA5 и 0AA7.
Значение pop всегда равно нулю.
Вызовем данную функцию, но для начала нам понадобится смещение на начало функции, получим его так:
Теперь сам вызов:
В данном случае у нас 1 параметр и функция возвращает значение в переменную 0.
Это самый простой способ вызова функций, пойдем дальше.
2)_cdecl void addDebugMessage(cSampChatInfo*, char* text, format...)
_cdecl позволяет вызывать функции с переменным количеством параметров.
Как выглядит в asm вызов addDebugMessage(sampChatInfo, text, var1, var2):
Выглядит сложнее, но можно разобраться.
Значение pop у нас равно значению num_params.
Заметим, что параметры передаются в обратном порядке и что стек отчищает вызываемая функция. Для вызова данной функции используем 0AA5. Но сначала нам надо получить адресс функции, воспользуемся связкой из прошлого примера:
Сам вызов:
После вызова функция выведет в чат “Example: 48 + 64”. Круто? Не то слово!
3)_thiscall void CDXUTDialog::SetBackgroundColors(DWORD clr1, DWORD clr2, _DWORD clr3, DWORD clr4);
thiscall — это аналог stdcall, но он выполняется для определенной структуры.
Как выглядит в asm dlg->SetBackgroundColors(0xffffffff, 0xff110011, 0xff000000, 0xff11ccdd):
Единственное отличие от cdecl – это помещение в регистр ecx смещение на начало структуры, из которой вызывается функция.
Для вызова данной функции используем 0AA6: (В 0@ указан samp_base)
После вызова данной функции верхний-левый угол диалога чата окрасится в серо-черный цвет (BB0050505).
Приведу простую напоминалку:
Сразу запомним особенность, опкоды с наличием function в названии отличаются от аналогичных опкодов без function только тем, что мы указываем в конце переменную, в которую запишется результат функции, в остальном они одинаковые.
Мы будем учиться использовать cdecl/stdcall/thiscall.
Для примера возьмем:
_stdcall HMODULE WINAPI GetModuleHandle(LPCTSTR lpModuleName);
_cdecl void addDebugMessage(cSampChatInfo*, char* text, format...);
_thiscall void CDXUTDialog::SetBackgroundColors(DWORD clr1, DWORD clr2, DWORD clr3, DWORD clr4);
1)_stdcall HMODULE WINAPI GetModuleHandle(LPCTSTR lpModuleName)
_stdcall позволяет вызывать функции с заданным для неё количеством параметров.
Как выглядит в asm вызов GetModuleHandle(“samp.dll”):
Код:
push offset//Указатель на текст
call GetModuleHandle
Для вызова stdcall используются 0AA5 и 0AA7.
Значение pop всегда равно нулю.
Вызовем данную функцию, но для начала нам понадобится смещение на начало функции, получим его так:
Код:
0AA2: 31@ = load_library "kernel32.dll" //Загружаем kernel32.dll
0AA4: 30@ = get_proc_address "GetModuleHandleA" library 31@ //Получаем смещение на начало функции
Код:
0AA7: call_function 30@ num_params 1 pop 0 "samp.dll" 0@
Это самый простой способ вызова функций, пойдем дальше.
2)_cdecl void addDebugMessage(cSampChatInfo*, char* text, format...)
_cdecl позволяет вызывать функции с переменным количеством параметров.
Как выглядит в asm вызов addDebugMessage(sampChatInfo, text, var1, var2):
Код:
push var2
push var1
push text
push sampChatInfo
call addDebugMessage
pop 10h//16 = 4 параметра * 4 байта каждый
Значение pop у нас равно значению num_params.
Заметим, что параметры передаются в обратном порядке и что стек отчищает вызываемая функция. Для вызова данной функции используем 0AA5. Но сначала нам надо получить адресс функции, воспользуемся связкой из прошлого примера:
Код:
0AA2: 31@ = load_library "kernel32.dll" // IF and SET
0AA4: 30@ = get_proc_address "GetModuleHandleA" library 31@ // IF and SET
0AA7: call_function 30@ num_params 1 pop 0 "samp.dll" 0@
Код:
0A8E: 1@ = 0@ + 0x212A24 //смещение указателя _cSampChatInfo
0A8D: 2@ = read_memory 1@ size 4 virtual_protect 1 //читаем указатель, получаем смещение на _cSampChatInfo
0A8E: 1@ = 0@ + 0x79680 // смещение фукнции addDebugMessage
0AA5: call 1@ num_params 4 pop 4 params 64 48 "Example: %d + %d" 2@ //вызываем
3)_thiscall void CDXUTDialog::SetBackgroundColors(DWORD clr1, DWORD clr2, _DWORD clr3, DWORD clr4);
thiscall — это аналог stdcall, но он выполняется для определенной структуры.
Как выглядит в asm dlg->SetBackgroundColors(0xffffffff, 0xff110011, 0xff000000, 0xff11ccdd):
Код:
push0xff11ccdd
push 0xff000000
push 0xff110011
push 0xffffffff
mov ecx, [dlg]
call SetBackgroundColors
Для вызова данной функции используем 0AA6: (В 0@ указан samp_base)
Код:
0A8E: 1@ = 0@ + 0x212AC4//Смещение на указатель на структуру
0A8D: 2@ = read_memory 1@ size 4 virtual_protect 1 //Читаем смещение на структуру
0A8E: 1@ = 0@ + 0x94D20//Смещение на функцию
0AA6: call_method 1@ struct 2@ num_params 4 pop 0 params 0x00050505 0x00050505 0x00050505 0xBB0050505//Вызываем функцию структуры
Приведу простую напоминалку: