Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Выгрузка модуля


Автор: ASGDeveloper 20.9.2006, 10:41
Большая просьба подсказать как можно выполнить реинжект модуля (без сторонних компонент типа madCodeHook).  


M
Girder
Поиск...
http://forum.vingrad.ru/index.php?showtopi...st&p=339720

Автор: Yanis 20.9.2006, 11:27
ASGDeveloper
Сегодня какой то непонятный день. Мож я невыспался smile
А что такое модуль?

Автор: ASGDeveloper 20.9.2006, 12:00
Цитата(Yanis @  20.9.2006,  11:27 Найти цитируемый пост)
А что такое модуль?

Ну обычная длл-ка. То есть, "инжект модуля" - это внедрение dll-ки в чужое адресное пространство, а "реинжект модуля" - это выгрузка dll-ки из чужого адресного пространства.

Делаю так:
Код

type
TFreeLibraryCode=packed record
 FreeLibPushOp: byte;
 FreeLibPushArg: dword;
 FreeLibCallOp: word;
 FreeLibCallArg: dword;
 ExitThreadPushOp: byte;
 ExitThreadPushArg: dword;
 ExitThreadCallOp: word;
 ExitThreadCallArg: dword;
 FreeLibraryAddress: dword;
 ExitThreadAddress: dword;
end;

function GetCodeBase(CodeSize: integer; pID: integer): Pointer;
var
 hProcess: integer;
begin
 hProcess:=OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_WRITE or PROCESS_VM_OPERATION, false, pID);
 result:=VirtualAllocEx(hProcess, nil, CodeSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 CloseHandle(hProcess);
end;

function ExCodeInRemoteProcess(pCode: Pointer; CodeSize: integer; CodeBase: Pointer; pID: integer): boolean;
var
 hProcess: integer;
 BytesWritten: Cardinal;
 hThread: integer;
 ThreadID: Cardinal;
begin
 hProcess:=OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_WRITE or PROCESS_VM_OPERATION, FALSE, pID);
 if (hProcess=0) then
  begin
   result:=false;
   exit;
  end;

 result:=WriteProcessMemory(hProcess, CodeBase, pCode, CodeSize, BytesWritten);
 if (not result) then
  begin
   CloseHandle(hProcess);  
   exit;
  end;

 hThread:=CreateRemoteThread(hProcess, nil, 0, CodeBase, nil, 0, ThreadID);
 if (hThread=0) then
  begin
   VirtualFreeEx(hProcess, CodeBase, CodeSize, MEM_RELEASE);
   CloseHandle(hProcess);
   result:=false;
   exit;
  end;

 WaitForSingleObject(hThread, INFINITE);
 VirtualFreeEx(hProcess, CodeBase, CodeSize, MEM_RELEASE);
 CloseHandle(hProcess);
 
 result:=true;
end;


function FreeLibraryInProcess(pID: integer; LibName: string): boolean;
var
 FreeLibraryCode: TFreeLibraryCode;
 pCode: Pointer;
 hLib: THandle;
begin
 pCode:=GetCodeBase(sizeof(FreeLibraryCode), pID);

 FreeLibraryCode.FreeLibPushOp:=OPCODE_PUSH;
 hLib:=LoadLibrary(PChar(LibName));
 FreeLibraryCode.FreeLibPushArg:=GetModuleHandle(PChar(LibName));
 FreeLibrary(hLib);
 FreeLibraryCode.FreeLibCallOp:=OPCODE_CALL;
 FreeLibraryCode.FreeLibCallArg:=DWORD(pCode)+DWORD(@FreeLibraryCode.FreeLibraryAddress)-DWORD(@FreeLibraryCode);

 FreeLibraryCode.ExitThreadPushOp:=OPCODE_PUSH;
 FreeLibraryCode.ExitThreadPushArg:=0;
 FreeLibraryCode.ExitThreadCallOp:=OPCODE_CALL;
 FreeLibraryCode.ExitThreadCallArg:=DWORD(pCode)+DWORD(@FreeLibraryCode.ExitThreadAddress)-DWORD(@FreeLibraryCode);

 FreeLibraryCode.FreeLibraryAddress:=DWORD(GetProcAddress(GetModuleHandle('kernel32.dll'), 'FreeLibrary'));
 FreeLibraryCode.ExitThreadAddress:=DWORD(GetProcAddress(GetModuleHandle('kernel32.dll'), 'ExitThread'));

 result:=ExCodeInRemoteProcess(@FreeLibraryCode, sizeof(FreeLibraryCode), pCode, pID);
end;

Автор: ne0n 20.9.2006, 16:18
Вот хороший код нарыл у себя:
Код

uses tlhelp32; 
 
procedure FreeLibraryPID(pID:Cardinal; NameDLL:string); 
type 
 TInjectCode=packed record 
  Push:Byte; 
  PushValue:DWord; 
  Call:Byte; 
  CallValue:DWord; 
  IsZero:Word; 
  JmpZero:Word; 
  Ret:Byte; 
 end; 
var H:THandle; 
    Module32:TModuleEntry32; 
    InjectCode:TInjectCode; 
    KernelDLL:DWord; 
    oProcess,oProcessThread:DWord; 
    PID_Mem:Pointer; 
    t:DWord; 
begin 
 InjectCode.CallValue:=0; 
 KernelDLL:=LoadLibrary('Kernel32.dll'); 
 if KernelDLL<>0 then 
  begin 
   InjectCode.CallValue:=DWord(GetProcAddress(KernelDLL,'FreeLibrary')); 
   FreeLibrary(KernelDLL); 
  end; 
 if (pID=0)or(InjectCode.CallValue=0) then exit; 
 oProcess:=OpenProcess(PROCESS_ALL_ACCESS,False,PID); 
 if oProcess=0 then exit; 
 PID_Mem:=VirtualAllocEx(oProcess,nil,SizeOf(InjectCode),MEM_RESERVE or MEM_COMMIT,PAGE_EXECUTE_READWRITE); 
 if PID_Mem=nil then 
  begin 
   CloseHandle(oProcess); 
   exit; 
  end; 
 NameDLL:=trim(NameDLL); 
 H:=CreateToolHelp32Snapshot(TH32CS_SNAPMODULE,pID); 
 if H<>INVALID_HANDLE_VALUE then 
  begin 
   InjectCode.Push:=$68; 
   InjectCode.Call:=$e8; 
   InjectCode.IsZero:=$C021; 
   InjectCode.JmpZero:=$F275; 
   InjectCode.Ret:=$C3; 
   Module32.dwSize:=SizeOf(TModuleEntry32); 
   if Module32First(H,Module32) then 
    repeat 
     if AnsiCompareText(NameDLL,Module32.szModule)=0 then 
      begin 
       InjectCode.PushValue:=DWord(Module32.modBaseAddr); 
       InjectCode.CallValue:=InjectCode.CallValue-DWord(PID_Mem)-10; 
       if (WriteProcessMemory(oProcess,PID_Mem,@InjectCode,SizeOf(InjectCode),t)and(t=SizeOf(InjectCode))) then 
        begin 
         oProcessThread:=CreateRemoteThread(oProcess,nil,0,PID_Mem,nil,0,t); 
         if oProcessThread<>0 then 
          begin 
          if WaitForSingleObject(oProcessThread,1000)<>WAIT_TIMEOUT then //Даем на выгрузку одну секунду. 
            ShowMessage('Один есть!'); 
           CloseHandle(oProcessThread); 
          end; 
        end; 
      end; 
    until (Module32Next(H,Module32)=false); 
   CloseHandle(H); 
  end; 
 VirtualFreeEx(oProcess,PID_Mem,0,MEM_RELEASE);   
 CloseHandle(oProcess); 
end; 
 


да кстати  "реинжект" делать можно только с динамичеси загруженными dll  smile 

Автор: ASGDeveloper 21.9.2006, 08:47
Цитата(ne0n @  20.9.2006,  16:18 Найти цитируемый пост)
Вот хороший код нарыл у себя:

О, сенкс!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)