AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi DLL Injection Code Port Question
Thema durchsuchen
Ansicht
Themen-Optionen

DLL Injection Code Port Question

Ein Thema von _jaromir_ · begonnen am 22. Jul 2008 · letzter Beitrag vom 23. Jul 2008
Antwort Antwort
_jaromir_

Registriert seit: 22. Jul 2008
4 Beiträge
 
Delphi 7 Enterprise
 
#1

DLL Injection Code Port Question

  Alt 22. Jul 2008, 07:19
Hallo,
I need to port the following code to delphi 7. So far it constantly crashes the target process, what do I need to do to fix? Please help.

Original code is here:
Zitat:
#define DLL_NAME "injected.dll"

__declspec(naked) loadDll(void)
{
_asm{
// Placeholder for the return address
push 0xDEADBEEF

// Save the flags and registers
pushfd
pushad

// Placeholder for the string address and LoadLibrary
push 0xDEADBEEF
mov eax, 0xDEADBEEF

// Call LoadLibrary with the string parameter
call eax

// Restore the registers and flags
popad
popfd

// Return control to the hijacked thread
ret
}
}

__declspec(naked) loadDll_end(void)
{
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
void *dllString;
void *stub;
unsigned long wowID, threadID, stubLen, oldIP, oldprot, loadLibAddy;
HANDLE hProcess, hThread;
CONTEXT ctx;

stubLen = (unsigned long)loadDll_end - (unsigned long)loadDll;

loadLibAddy = (unsigned long)GetProcAddress(GetModuleHandle("kernel32.dll" ), "LoadLibraryA");

wowID = GetTargetProcessIdFromProcname(PROC_NAME);
hProcess = OpenProcess((PROCESS_VM_WRITE | PROCESS_VM_OPERATION), false, wowID);

dllString = VirtualAllocEx(hProcess, NULL, (strlen(DLL_NAME) + 1), MEM_COMMIT, PAGE_READWRITE);
stub = VirtualAllocEx(hProcess, NULL, stubLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, dllString, DLL_NAME, strlen(DLL_NAME), NULL);

threadID = GetTargetThreadIdFromProcname(PROC_NAME);
hThread = OpenThread((THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME), false, threadID);
SuspendThread(hThread);

ctx.ContextFlags = CONTEXT_CONTROL;
GetThreadContext(hThread, &ctx);
oldIP = ctx.Eip;
ctx.Eip = (DWORD)stub;
ctx.ContextFlags = CONTEXT_CONTROL;

VirtualProtect(loadDll, stubLen, PAGE_EXECUTE_READWRITE, &oldprot);
memcpy((void *)((unsigned long)loadDll + 1), &oldIP, 4);
memcpy((void *)((unsigned long)loadDll + 8 ), &dllString, 4);
memcpy((void *)((unsigned long)loadDll + 13), &loadLibAddy, 4);

WriteProcessMemory(hProcess, stub, loadDll, stubLen, NULL);
SetThreadContext(hThread, &ctx);

ResumeThread(hThread);

Sleep(8000);

VirtualFreeEx(hProcess, dllString, strlen(DLL_NAME), MEM_DECOMMIT);
VirtualFreeEx(hProcess, stub, stubLen, MEM_DECOMMIT);
CloseHandle(hProcess);
CloseHandle(hThread);

return 0;
}
Here is my code but it is broken.

Delphi-Quellcode:
function OpenThread(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwThreadId: DWORD): DWORD; stdcall;
external 'kernel32.dll';

const
 THREAD_GET_CONTEXT = $0008;
 THREAD_SET_CONTEXT = $0010;
 THREAD_SUSPEND_RESUME = $0002;

procedure loadDll; assembler;
asm
      push $DEADBEEF // EIP
      pushfd
      pushad
      push $DEADBEEF // memory with dll name
      mov eax, $DEADBEEF // loadlibrary address
      call eax
      popad
      popfd
      ret
end;

procedure dEnd; assembler;
asm

end;

procedure InjectLib(const PID, TID: DWORD; DLL_NAME: PChar);
var
   stub, dllString: Pointer;
  stubLen, oldIP, oldprot, loadLibAddy, ret: DWORD;
  hProcess, hThread: THandle;
  ctx: CONTEXT;
  begin
   stubLen := DWORD(@dEnd) - DWORD(@loadDll);

   loadLibAddy := DWORD(GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryA'));

   hProcess := OpenProcess(PROCESS_VM_WRITE or PROCESS_VM_OPERATION, False, PID);

   dllString := VirtualAllocEx(hProcess, nil, (lstrlen(DLL_NAME)+1), MEM_COMMIT, PAGE_READWRITE);
   stub := VirtualAllocEx(hProcess, nil, stubLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
   WriteProcessMemory(hProcess, dllString, DLL_NAME, lstrlen(DLL_NAME), ret);

   hThread := OpenThread(THREAD_GET_CONTEXT or THREAD_SET_CONTEXT or THREAD_SUSPEND_RESUME, false, TID);
   SuspendThread(hThread);

   ZeroMemory(@ctx, sizeof(ctx));

   ctx.ContextFlags := CONTEXT_CONTROL;
   GetThreadContext(hThread, ctx);
   oldIP := ctx.Eip;
   ctx.Eip := DWORD(stub);
   ctx.ContextFlags := CONTEXT_CONTROL;

   VirtualProtect(@loadDll, stubLen, PAGE_EXECUTE_READWRITE, @oldprot);

   CopyMemory(pointer(dword(@loaddll) + 1), @oldIP, 4);
   CopyMemory(pointer(dword(@loaddll) + 8), dllString, 4);
   CopyMemory(pointer(dword(@loaddll) + 13), @loadLibAddy, 4);

   WriteProcessMemory(hProcess, stub, @loaddll, stubLen, ret);

   SetThreadContext(hThread, ctx);

   ResumeThread(hThread);

   Sleep(8000);

   VirtualFreeEx(hProcess, dllString, strlen(DLL_NAME), MEM_DECOMMIT);
   VirtualFreeEx(hProcess, stub, stubLen, MEM_DECOMMIT);
   CloseHandle(hProcess);
   CloseHandle(hThread);
end;
JR
  Mit Zitat antworten Zitat
Benutzerbild von nicodex
nicodex

Registriert seit: 2. Jan 2008
Ort: Darmstadt
286 Beiträge
 
Delphi 2007 Professional
 
#2

Re: DLL Injection Code Port Question

  Alt 22. Jul 2008, 07:51
Code:
ResumeThread(hThread);
Sleep(8000);
This is bad design, use WaitForSingleObject.
Thread Context Hijacking is unsafe, you should use "ready-to-use-and-working-due-to-years-of-research-and-testing" libraries for this purpose (e.g. http://www.madshi.net ).
  Mit Zitat antworten Zitat
_jaromir_

Registriert seit: 22. Jul 2008
4 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: DLL Injection Code Port Question

  Alt 22. Jul 2008, 07:59
Nicodex
I understand this and you are right but I have to know why the example in c is not working in delphi? I do not care about reliability as it is for my code porting knowledge, not for use in applications for users. I just want to make it work as the c example, any help please? I believe the loadDll part is problem maybe, everything else seems ok from my view.
JR
  Mit Zitat antworten Zitat
Benutzerbild von nicodex
nicodex

Registriert seit: 2. Jan 2008
Ort: Darmstadt
286 Beiträge
 
Delphi 2007 Professional
 
#4

Re: DLL Injection Code Port Question

  Alt 22. Jul 2008, 08:15
Zitat von _jaromir_:
I believe the loadDll part is problem maybe, everything else seems ok from my view.
Currently I do not have the time to verify the whole code, sorry.

You are right about loadDll. Make sure / verify that the Delphi compiler does not generate stack frame code for the function (set a breakpoint on the "asm" statement of the function and take look at the CPU window.
For sanity reasons you might want to use a hand-crafted packed record with the target code.
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#5

Re: DLL Injection Code Port Question

  Alt 22. Jul 2008, 17:36
copymemory..(@dllstring)
  Mit Zitat antworten Zitat
_jaromir_

Registriert seit: 22. Jul 2008
4 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: DLL Injection Code Port Question

  Alt 22. Jul 2008, 23:35
Hallo Brechi,
Even after change still same result and crash target process. I updated the code entirely and it still doing this! I will post updated code using packed record of assembly.
JR
  Mit Zitat antworten Zitat
_jaromir_

Registriert seit: 22. Jul 2008
4 Beiträge
 
Delphi 7 Enterprise
 
#7

Re: DLL Injection Code Port Question

  Alt 22. Jul 2008, 23:48
Delphi-Quellcode:

type injt = packed record
 PushCommand: Byte; // 0x68
 PushEIP: DWORD; // Old EIP value from context to return to
 PushFd: Byte; // 0x9c
 PushAd: Byte; //0x60
 PushCommand2: Byte; // 0x68
 PushDLLName: DWORD; // address of LibraryName
 Call: Word; // 15ff
 CallAddr: DWORD; //LoadLibraryA address
 PopAd: Byte; // 0x61
 PopFd: Byte; // 0x9d
 Ret: Byte; // 0xc3
 AddrLoadLibrary: DWORD;
 LibraryName: array [0..MAX_PATH] of char;
 end;

procedure InjectLib(const PID, TID: DWORD);
var
  stubLen, oldIP, ret: DWORD;
  hProcess, hThread: THandle;
  ctx: CONTEXT;
    n: injt;
 stub: Pointer;
  begin

   stubLen := sizeof(n);

   hProcess := OpenProcess(PROCESS_VM_WRITE or PROCESS_VM_OPERATION, False, PID);

   if hProcess = 0 then exit;

   stub := VirtualAllocEx(hProcess, nil, stubLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

   hThread := OpenThread(THREAD_GET_CONTEXT or THREAD_SET_CONTEXT or THREAD_SUSPEND_RESUME, false, TID);

   if hThread = 0 then exit;

   SuspendThread(hThread);

   ZeroMemory(@ctx, sizeof(ctx));

   ctx.ContextFlags := CONTEXT_CONTROL;
   GetThreadContext(hThread, ctx);
   oldIP := ctx.Eip;
   ctx.Eip := DWORD(stub);
   ctx.ContextFlags := CONTEXT_CONTROL;


 with n do
 begin
 PushCommand := $68;
 PushEIP := oldIP;
 pushfd := $9c;
 pushad := $60 ;
 PushCommand2 := $68;
 PushDLLName := DWORD(stub) + 25;
 call := $15FF;
 calladdr := DWORD(stub) + 21;
 PopAd := $61;
 PopFd := $9d;
 ret := $c3;
 StrPCopy(@LibraryName, 'psapi.dll');
 AddrLoadLibrary := DWORD(GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryA'));
end;

   WriteProcessMemory(hProcess, stub, @n, stubLen, ret);

   SetThreadContext(hThread, ctx);

   ResumeThread(hThread);

   WaitForSingleObject(hThread, INFINITE);

   VirtualFreeEx(hProcess, stub, stubLen, MEM_DECOMMIT);
   CloseHandle(hProcess);
   CloseHandle(hThread);
end;
Still crashes target process =(. I think the error is somewhere else and maybe in context set?
JR
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#8

Re: DLL Injection Code Port Question

  Alt 23. Jul 2008, 07:51
The old code was working for me with my changes i posted above.

Do an int3 at the beginning of the injected code and debug with a just in time debugger (ex. ollydbg).

Be sure you dont inject to fast afher target process start. Dllmain must be executed (if you create the process yourself with CREATE_SUSPENDED, its pauses at system breakpoint not dllmain).

Be Sure the Thread is stopped. Suspend Thread suspends the Thread only if the Result value is -1 or 0. Its like a counter. If someone calls Resumethread mroe times on the threadid it is increased. You have to call SuspendThread until its really suspended!

There are also some more bugs with this method
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:35 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz