Всем привет! Прошу вашей помощи так как сам пока что не могу осилить.... В общем ситуация такая. Есть DLL-ка engine.dll. В ней есть функция, НЕ экспортируемая. (но по идеи называться она должна __thiscall ... :: SendPacket(...) У меня есть на неё адрес. По сути она передает пакет на отправку серверу. Мне надо сделать проверку, с какого файла идет вызов этой функции. Например проверить, если вызов идет НЕ с engine.dll - то выполняем какой то код (ну например закрываем приложение) ---- Чуть знаю Delphi и FASM. Но очень прошу написать более-менее понятным новичку языком) Очень надеюсь на Вашу помощь.
Ну есть файл engine.dll там есть функция. Мне надо сделать так что бы она НЕ вызывалась с других файлов (что бы не хукали функцию)
очевидное решение - перехватить ее и проверять вдрес откуда ее вызвают (адрес возврата) не менее очевидно, что такое решение легко обойти судя по уровню вопроса, малореально что ТС создаст защиту которую не смогут обойти
Словосочетание НЕ вызывалась с других файлов безграмотно и лишено смысла. Из файлов ничего не может вызываться. Нет простых способов, чтобы не хукали. Детектировать хук можно, как сказали выше, проверяя адрес возврата.
ТС хочет что бы функцию из длл вызывыл толшько определенный файл ПЕ. Прогверяй адрес возврата и смотри какому модулю он прингадлежит
А можно подробнее как его проверить? Или дайте ссылочку где можно почитать. Ну или примерный код Заранее спасибо
взять адрес возврата со стека и проверить лежит ли он в диапазоне [базовый адрес длл, базовый адрес длл + размер образа]... на каком языке написана длл? если у вас нет исходных кодов, то можно в рантайме сплайсить функцию и уже в своем обработчике делать проверку...
Код (Text): .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib .code true_modul db 'Project.exe',0 start: call MyFunc ret MyFunc: ;EP your function pop eax ;здесь нужно вытащить адрес возврата push eax ;кодес может быт другим @@: dec eax xor al,al cmp word ptr[eax],'ZM' jnz @b mov ebx,0ffh sub esp,ebx mov esi,esp push ebx push esi push eax call GetModuleFileName xchg ecx,eax jecxz falsemodul add esi,ecx @@: dec esi cmp byte ptr[esi-1],'\' jnz @b push esi push offset true_modul call lstrcmp add esp,ebx xchg eax,ecx jecxz truecall falsemodul: ret truecall: ;playload nop nop nop int 3 ret end start
TrashGen с возвращением, товарищ! тссс, я без палева по кодесу это явно не Дельфи как ТС хочет но как-то так пусть реализовывает, принцип ясен Код (Text): var s: AnsiString begin SetLength(s, MAX_PATH); GetModuleFileNameA(nil, @s[1], MAX_PATH); if ... end.
В общем сейчас код моей программы выглядит приблизительно так. Код (Text): library nProtect; uses Windows, sysutils, Registry, classes, tlhelp32; {$E des} const ReplyGameGuardQuery = '?ReplyGameGuardQuery@UNetworkHandler@@UAEXKKKK@Z'; cdddd: PChar = 'cSSSd'#0; {$R *.RES} type mas1 = array [1..64] of WideChar; var DllHandle: THandle; Reg: TRegistry; Offset: DWORD; SENDPACKET,pSENDPACKET: DWORD; minaddress, maxaddress,imagesize : DWORD; Hlapex: Byte; ReplyGameGuardQueryAddr: PByte; PacketHdr: DWord; ID:String; key: Integer; WindowList,NamesList, PEList: TSTringList; SWC_1,SWC_2,SIP: mas1; pSWC_1,pSWC_2,pIP:Pointer; IP:String; //================================================================== function KillTask(ExeFileName:string):integer; ..... код который киляет процесс .... end; //================================================================ function GetHardID:string; ... серийник диска..... end; //=================================================================== function FindIllegalSowtware(hwnd: THandle; lParam: Longint): Boolean; stdcall; ... Поиск "плохих" программ по имени процесса ..... end; procedure ScanPe; .... end; //================================================================ procedure CheckEnv; stdcall; begin EnumWindows(@FindIllegalSowtware,0); if Hlapex <> 4 then ScanPe; PacketHdr := Hlapex; end; //================================================================ procedure GGReplay; cdecl; asm push esp push ecx call CheckEnv pop ecx pop esp mov eax,[ecx+048h] mov ecx,[eax] //------------------- mov edx, [PacketHdr] push edx mov edx, pIP push edx mov edx, pSWC_2 push edx mov edx, pSWC_1 push edx push $CB push cdddd push eax mov eax, [ecx+06Ch] //-----------------------, // вот и узнали адрес SendPacket. её надо защитить mov SENDPACKET, eax mov pSENDPACKET, ecx call eax //---------------------- add esp,$1c ret $10 end; procedure AntiIngame; cdecl; asm end; //================================================================ procedure doHandle(blackList: Pchar); var St: TStringList; S: String; i: Integer; begin .... всякая фигня..... DllHandle := GetModuleHandle('engine.dll'); minaddress := DllHandle; .... сплайсинг ответа на сервер.... if DllHandle <> 0 then begin ReplyGameGuardQueryAddr := GetProcAddress(DllHandle,ReplyGameGuardQuery); if NOT assigned(ReplyGameGuardQueryAddr) then exit; if VirtualProtectEx(GetCurrentProcess,ReplyGameGuardQueryAddr,10,PAGE_EXECUTE_READWRITE,Offset) then begin ReplyGameGuardQueryAddr^ := $E9; Offset := Dword(@GGReplay)-DWord(ReplyGameGuardQueryAddr)-5; move(Offset,Pointer(DWord(ReplyGameGuardQueryAddr)+1)^,sizeof(Offset)); end; DisableThreadLibraryCalls(GetModuleHandle(nil)); end; EnumWindows(@FindIllegalSowtware,0); ScanPe; end; exports doHandle; begin end. в procedure AntiIngame; cdecl; asm я думаю и надо сделать проверку вызова. procedure AntiIngame; cdecl; begin asm pop eax push eax mov [pEAX], eax end; if (pEAX> GetModuleHandle('engine.dll') AND pEAX< (GetModuleHandle('engine.dll')+ IMAGE_SIZE)) then ... else ... типо так делать или как? И что значит "Размер образа"? Как его получить?
размер длл в виртуальной памяти процесса с учетом выравнивания по размеру страниц виртуальной памяти... каждая секция pe-файла выравнивается на размер страницы, и вообще говоря в заголовках pe-файла есть соответствующее поле... можно считать оттуда, или же руками посчитать количество выделенных страниц)
В общем сейчас подпрограмма выглядит так Код (Text): procedure AntiIngame; cdecl; begin asm pop eax push eax mov stack,eax end; if (stack < minaddress) OR (stack > maxaddress) then MessageBox(0,'InGame bot detected','ALF Protection System',MB_ICONSTOP); end; DllHandle := GetModuleHandle('engine.dll'); minaddress := DllHandle; maxaddress := minaddress+$19C9C00; сплайсинг вот так SENDPACKET^ := $E9; Offset := Dword(@AntiIngame)-DWord(SENDPACKET)-5; move(Offset,Pointer(DWord(SENDPACKET)+1)^,sizeof(Offset)); Нормально?
TrashGen Jcx очень, очень не желательная для использования группа инструкций. Хотя тут наверно не критично.. Rel LDR_DATA_TABLE_ENTRY.SizeOfImage[LdrFindEntryForAddress(DWORD[Esp])].