Защитить функцию от вызова с других приложений

Тема в разделе "WASM.BEGINNERS", создана пользователем r2max, 5 апр 2011.

  1. r2max

    r2max Женя

    Публикаций:
    0
    Регистрация:
    30 мар 2011
    Сообщения:
    40
    Адрес:
    Киев
    Всем привет!

    Прошу вашей помощи так как сам пока что не могу осилить....
    В общем ситуация такая.
    Есть DLL-ка engine.dll.
    В ней есть функция, НЕ экспортируемая. (но по идеи называться она должна __thiscall ... :: SendPacket(...)
    У меня есть на неё адрес.
    По сути она передает пакет на отправку серверу.
    Мне надо сделать проверку, с какого файла идет вызов этой функции.
    Например проверить, если вызов идет НЕ с engine.dll - то выполняем какой то код (ну например закрываем приложение)
    ----
    Чуть знаю Delphi и FASM. Но очень прошу написать более-менее понятным новичку языком)
    Очень надеюсь на Вашу помощь.
     
  2. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    Ничего не понял.
     
  3. r2max

    r2max Женя

    Публикаций:
    0
    Регистрация:
    30 мар 2011
    Сообщения:
    40
    Адрес:
    Киев
    Ну есть файл engine.dll
    там есть функция.
    Мне надо сделать так что бы она НЕ вызывалась с других файлов (что бы не хукали функцию)
     
  4. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    очевидное решение - перехватить ее и проверять вдрес откуда ее вызвают (адрес возврата)
    не менее очевидно, что такое решение легко обойти

    судя по уровню вопроса, малореально что ТС создаст защиту которую не смогут обойти
     
  5. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    Словосочетание НЕ вызывалась с других файлов безграмотно и лишено смысла. Из файлов ничего не может вызываться.

    Нет простых способов, чтобы не хукали. Детектировать хук можно, как сказали выше, проверяя адрес возврата.
     
  6. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    ТС хочет что бы функцию из длл вызывыл толшько определенный файл ПЕ.
    Прогверяй адрес возврата и смотри какому модулю он прингадлежит
     
  7. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    а вот если что бы не хукали это вам батенька весь васм перечитывать
     
  8. r2max

    r2max Женя

    Публикаций:
    0
    Регистрация:
    30 мар 2011
    Сообщения:
    40
    Адрес:
    Киев
    А можно подробнее как его проверить?
    Или дайте ссылочку где можно почитать.
    Ну или примерный код
    Заранее спасибо
     
  9. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.250
    взять адрес возврата со стека и проверить лежит ли он в диапазоне [базовый адрес длл, базовый адрес длл + размер образа]... на каком языке написана длл? если у вас нет исходных кодов, то можно в рантайме сплайсить функцию и уже в своем обработчике делать проверку...
     
  10. TrashGen

    TrashGen ТрещГен

    Публикаций:
    0
    Регистрация:
    15 мар 2011
    Сообщения:
    1.173
    Адрес:
    подполье
    Код (Text):
    1.     .386
    2.     .model flat,stdcall
    3.     option casemap:none
    4.     include \masm32\include\windows.inc
    5.     include \masm32\include\kernel32.inc
    6.     includelib \masm32\lib\kernel32.lib
    7. .code
    8. true_modul db 'Project.exe',0
    9. start:
    10.  
    11. call MyFunc
    12. ret
    13.  
    14. MyFunc: ;EP your function
    15. pop eax ;здесь нужно вытащить адрес возврата
    16. push eax    ;кодес может быт другим
    17. @@:
    18.     dec eax
    19.     xor al,al
    20.     cmp word ptr[eax],'ZM'
    21. jnz @b
    22. mov ebx,0ffh
    23. sub esp,ebx
    24. mov esi,esp
    25.     push ebx
    26.     push esi
    27.     push eax
    28.     call GetModuleFileName
    29. xchg ecx,eax
    30. jecxz falsemodul
    31. add esi,ecx
    32. @@:
    33.     dec esi
    34.     cmp byte ptr[esi-1],'\'
    35. jnz @b 
    36. push esi
    37. push offset true_modul
    38. call lstrcmp
    39. add esp,ebx
    40. xchg eax,ecx
    41. jecxz truecall
    42. falsemodul:
    43.     ret
    44. truecall:
    45.     ;playload
    46.     nop
    47.     nop
    48.     nop
    49.     int 3
    50. ret
    51.  
    52. end start
     
  11. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    TrashGen
    с возвращением, товарищ! тссс, я без палева :lol:

    по кодесу это явно не Дельфи как ТС хочет :)

    но как-то так пусть реализовывает, принцип ясен
    Код (Text):
    1. var
    2. s: AnsiString
    3. begin
    4. SetLength(s, MAX_PATH);
    5. GetModuleFileNameA(nil, @s[1], MAX_PATH);
    6.  
    7. if ...
    8. end.
     
  12. r2max

    r2max Женя

    Публикаций:
    0
    Регистрация:
    30 мар 2011
    Сообщения:
    40
    Адрес:
    Киев
    В общем сейчас код моей программы выглядит приблизительно так.
    Код (Text):
    1. library nProtect;
    2.  
    3. uses
    4.   Windows,
    5.   sysutils,
    6.   Registry,
    7.   classes,
    8.   tlhelp32;
    9. {$E des}
    10.  
    11. const
    12. ReplyGameGuardQuery = '?ReplyGameGuardQuery@UNetworkHandler@@UAEXKKKK@Z';
    13.  cdddd: PChar = 'cSSSd'#0;
    14. {$R *.RES}
    15. type mas1 = array [1..64] of WideChar;
    16. var DllHandle: THandle;
    17.     Reg: TRegistry;
    18.     Offset: DWORD; 
    19.     SENDPACKET,pSENDPACKET: DWORD; 
    20.     minaddress, maxaddress,imagesize : DWORD;
    21.     Hlapex: Byte;
    22.     ReplyGameGuardQueryAddr: PByte;
    23.     PacketHdr: DWord;
    24.     ID:String;
    25.     key: Integer;
    26.     WindowList,NamesList, PEList: TSTringList;
    27.     SWC_1,SWC_2,SIP: mas1;
    28.     pSWC_1,pSWC_2,pIP:Pointer;
    29.     IP:String;
    30.  
    31. //==================================================================
    32. function KillTask(ExeFileName:string):integer;
    33. ..... код который киляет процесс ....
    34. end;
    35.  
    36. //================================================================
    37. function GetHardID:string;
    38. ... серийник диска.....
    39. end;
    40.  
    41. //===================================================================
    42. function FindIllegalSowtware(hwnd: THandle; lParam: Longint): Boolean; stdcall;
    43. ... Поиск "плохих" программ по имени процесса .....
    44. end;
    45.  
    46. procedure ScanPe;
    47. ....
    48. end;
    49. //================================================================
    50. procedure CheckEnv; stdcall;
    51. begin
    52.  EnumWindows(@FindIllegalSowtware,0);
    53.  if Hlapex <> 4 then ScanPe;
    54.  PacketHdr := Hlapex;
    55. end;
    56. //================================================================
    57. procedure GGReplay; cdecl;
    58. asm
    59.  push esp
    60.  push ecx
    61.   call CheckEnv
    62.   pop ecx
    63.   pop esp
    64.   mov eax,[ecx+048h]
    65.   mov ecx,[eax]
    66.   //-------------------
    67.   mov  edx, [PacketHdr]
    68.   push edx
    69.   mov  edx, pIP
    70.   push edx
    71.   mov  edx, pSWC_2
    72.   push edx
    73.   mov  edx, pSWC_1
    74.   push edx
    75.   push $CB
    76.   push cdddd
    77.   push eax
    78.   mov  eax, [ecx+06Ch]
    79.   //-----------------------,
    80.  // вот и узнали адрес SendPacket. её надо защитить
    81.   mov SENDPACKET, eax
    82.   mov pSENDPACKET, ecx
    83.   call eax
    84.   //----------------------
    85.   add esp,$1c
    86.   ret $10
    87. end;
    88.  
    89. procedure AntiIngame; cdecl;
    90. asm
    91.  
    92. end;
    93. //================================================================
    94. procedure doHandle(blackList: Pchar);
    95. var St: TStringList;
    96.     S: String;
    97.     i: Integer;
    98. begin
    99.   .... всякая фигня.....
    100.  
    101.    DllHandle := GetModuleHandle('engine.dll');
    102.    minaddress := DllHandle;
    103.    .... сплайсинг ответа на сервер....
    104.    if DllHandle <> 0 then begin
    105.     ReplyGameGuardQueryAddr := GetProcAddress(DllHandle,ReplyGameGuardQuery);
    106.     if NOT assigned(ReplyGameGuardQueryAddr) then exit;
    107.     if VirtualProtectEx(GetCurrentProcess,ReplyGameGuardQueryAddr,10,PAGE_EXECUTE_READWRITE,Offset) then begin
    108.      ReplyGameGuardQueryAddr^ := $E9;
    109.      Offset := Dword(@GGReplay)-DWord(ReplyGameGuardQueryAddr)-5;
    110.      move(Offset,Pointer(DWord(ReplyGameGuardQueryAddr)+1)^,sizeof(Offset));
    111.     end;
    112.    DisableThreadLibraryCalls(GetModuleHandle(nil));
    113.    end;
    114.    EnumWindows(@FindIllegalSowtware,0);
    115.    ScanPe;
    116. end;
    117.  
    118. exports
    119.    doHandle;
    120. begin
    121. 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
    ...
    типо так делать или как?
    И что значит "Размер образа"?
    Как его получить?
     
  13. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.250
    размер длл в виртуальной памяти процесса с учетом выравнивания по размеру страниц виртуальной памяти... каждая секция pe-файла выравнивается на размер страницы, и вообще говоря в заголовках pe-файла есть соответствующее поле... можно считать оттуда, или же руками посчитать количество выделенных страниц)
     
  14. r2max

    r2max Женя

    Публикаций:
    0
    Регистрация:
    30 мар 2011
    Сообщения:
    40
    Адрес:
    Киев
    А Можно примерчик какой то?)
     
  15. r2max

    r2max Женя

    Публикаций:
    0
    Регистрация:
    30 мар 2011
    Сообщения:
    40
    Адрес:
    Киев
    В общем сейчас подпрограмма выглядит так
    Код (Text):
    1. procedure AntiIngame; cdecl;
    2. begin
    3.     asm
    4.     pop eax
    5.     push eax
    6.     mov stack,eax
    7.     end;
    8. if (stack < minaddress) OR (stack > maxaddress) then
    9.     MessageBox(0,'InGame bot detected','ALF Protection System',MB_ICONSTOP);
    10. 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));
    Нормально?
     
  16. r2max

    r2max Женя

    Публикаций:
    0
    Регистрация:
    30 мар 2011
    Сообщения:
    40
    Адрес:
    Киев
    Всем спасибо)
    Тему можно закрывать)
     
  17. gaeprust

    gaeprust New Member

    Публикаций:
    0
    Регистрация:
    2 май 2011
    Сообщения:
    188
    TrashGen
    Jcx очень, очень не желательная для использования группа инструкций. Хотя тут наверно не критично..

    Rel
    LDR_DATA_TABLE_ENTRY.SizeOfImage[LdrFindEntryForAddress(DWORD[Esp])].