 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
Luig Cheater
Reputation: 0
Joined: 24 Sep 2010 Posts: 26
|
Posted: Wed Feb 23, 2011 8:39 pm Post subject: .dll injection from Free Pascal |
|
|
Alright, I finally created a working injectable .dll trainer in free pascal although it ended up being 11.8 mb in size. Now I want some way to inject the .dll from Free Pascal. The following code ends up in an access violation.
| Code: | Function InjectDll(ProcessID: DWORD; LibraryName: String): Integer;
const
MAX_LIBRARYNAME = MAX_PATH;
MAX_FUNCTIONNAME = 255;
MIN_INSTRSIZE = 5;
Type
PLibRemote = ^TLibRemote;
TLibRemote = packed record
ProcessID: DWORD;
LibraryName: Array [0..MAX_LIBRARYNAME] of Char;
LibraryHandle: HMODULE;
end;
var hKernel: HMODULE;
hProcess: THandle;
hThread: THandle;
dwNull: Cardinal;
lpRemote: PLibRemote;
lpLibRemote: PChar;
Begin
// Set default result of (-1), which means the injection failed
result:=(-1);
// Check library name and version of OS we are running on
if (Length(LibraryName) > 0) and ((GetVersion and $80000000) = 0)then
begin
Result := 2;
// Attempt to open the process
hProcess:=OpenProcess(PROCESS_VM_OPERATION, False, ProcessID);
// Check process handle
if (hProcess <> 0) then
begin
// Resource protection
try
Result:= 3;
// Get module handle for kernel32
hKernel:=GetModuleHandle('kernel32.dll');
// Check handle
if (hKernel <> 0) then
begin
Result := 4;
// Allocate memory in other process
lpLibRemote:=VirtualAllocEx(hProcess, nil, Succ(Length(LibraryName)), MEM_COMMIT, PAGE_READWRITE);
// Check memory pointer
if Assigned(lpLibRemote) then
begin
// Resource protection
try
Result := 5;
// Write the library name to the memory in other process
WriteProcessMemory(hProcess, lpLibRemote, PChar(LibraryName), Length(LibraryName), dwNull);
// Create the remote thread
hThread:=CreateRemoteThread(hProcess, nil, 0, GetProcAddress(hKernel, 'LoadLibraryA'), lpLibRemote, 0, dwNull);
// Check the thread handle
if (hThread <> 0) then
begin
// Resource protection
try
// Allocate a new remote injection record
lpRemote:=AllocMem(SizeOf(TLibRemote));
// Set process id
lpRemote^.ProcessID:=ProcessID;
// Copy library name
StrPLCopy(lpRemote^.LibraryName, LibraryName, MAX_LIBRARYNAME);
// Wait for the thread to complete
WaitForSingleObject(hThread, INFINITE);
// Fill in the library handle
GetExitCodeThread(hThread, DWORD(lpRemote^.LibraryHandle));
// Add to list
result:=1;
finally
// Close the thread handle
CloseHandle(hThread);
end;
end;
finally
// Free allocated memory
VirtualFree(lpLibRemote, 0, MEM_RELEASE);
end;
end;
end;
finally
// Close the process handle
CloseHandle(hProcess);
end;
end;
end;
End; |
Calling it like this:
| Code: | procedure TForm1.Button2Click(Sender: TObject);
Var
PID:DWORD;
WHnd:THandle;
Check:Integer;
begin
Whnd := FindWindow(nil, 'Adobe Flash Player 9');
GetWindowThreadProcessID(Whnd, @PID);
Check := InjectDll(PID, ExtractFilePath(Application.ExeName + 'SpeedHack.dll'));
ShowMessage('Successfully injected .dll');
ShowMessage(IntToStr(Check));
end; |
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25856 Location: The netherlands
|
Posted: Wed Feb 23, 2011 8:45 pm Post subject: |
|
|
tip to cut down on the size:
project options->linking. Untick dsplay line numbers and tick "Strip symbols from executable"
as for the crash, where does the exception happen. Game or injector?
Anyhow,
| Code: |
Check := InjectDll(PID, ExtractFilePath(Application.ExeName + 'SpeedHack.dll'));
|
I'd change it to
Check := InjectDll(PID, ExtractFilePath(Application.ExeName) + 'SpeedHack.dll');
and I'd also add PROCESS_VM_WRITE PROCESS_VM_READ , PROCESS_CREATE_THREAD and PROCESS_QUERY_INFORMATION to openprocess
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
Luig Cheater
Reputation: 0
Joined: 24 Sep 2010 Posts: 26
|
Posted: Wed Feb 23, 2011 9:02 pm Post subject: |
|
|
Thanks for the quick reply Dark Byte and tips. This is my following code and I still get Access Violation.
| Code: | procedure TForm1.Button2Click(Sender: TObject);
Var
PID:DWORD;
WHnd:THandle;
Check:Integer;
begin
Whnd := FindWindow(nil, 'Adobe Flash Player 9');
GetWindowThreadProcessID(Whnd, @PID);
Check := InjectDll(PID, ExtractFilePath(Application.ExeName) + 'SpeedHack.dll');
ShowMessage('Successfully injected .dll');
ShowMessage(IntToStr(Check));
end;
Function InjectDll(ProcessID: DWORD; LibraryName: String): Integer;
const
MAX_LIBRARYNAME = MAX_PATH;
MAX_FUNCTIONNAME = 255;
MIN_INSTRSIZE = 5;
Type
PLibRemote = ^TLibRemote;
TLibRemote = packed record
ProcessID: DWORD;
LibraryName: Array [0..MAX_LIBRARYNAME] of Char;
LibraryHandle: HMODULE;
end;
var hKernel: HMODULE;
hProcess: THandle;
hThread: THandle;
dwNull: Cardinal;
lpRemote: PLibRemote;
lpLibRemote: PChar;
Begin
// Set default result of (-1), which means the injection failed
result:=(-1);
// Check library name and version of OS we are running on
if (Length(LibraryName) > 0) and ((GetVersion and $80000000) = 0)then
begin
Result := 2;
// Attempt to open the process
hProcess:=OpenProcess(PROCESS_VM_OPERATION+PROCESS_CREATE_THREAD+PROCESS_QUERY_INFORMATION , False, ProcessID);
// Check process handle
if (hProcess <> 0) then
begin
// Resource protection
try
Result:= 3;
// Get module handle for kernel32
hKernel:=GetModuleHandle('kernel32.dll');
// Check handle
if (hKernel <> 0) then
begin
Result := 4;
// Allocate memory in other process
lpLibRemote:=VirtualAllocEx(hProcess, nil, Succ(Length(LibraryName)), MEM_COMMIT, PAGE_READWRITE);
// Check memory pointer
if Assigned(lpLibRemote) then
begin
// Resource protection
try
Result := 5;
// Write the library name to the memory in other process
WriteProcessMemory(hProcess, lpLibRemote, PChar(LibraryName), Length(LibraryName), dwNull);
// Create the remote thread
hThread:=CreateRemoteThread(hProcess, nil, 0, GetProcAddress(hKernel, 'LoadLibraryA'), lpLibRemote, 0, dwNull);
// Check the thread handle
if (hThread <> 0) then
begin
// Resource protection
try
// Allocate a new remote injection record
lpRemote:=AllocMem(SizeOf(TLibRemote));
// Set process id
lpRemote^.ProcessID:=ProcessID;
// Copy library name
StrPLCopy(lpRemote^.LibraryName, LibraryName, MAX_LIBRARYNAME);
// Wait for the thread to complete
WaitForSingleObject(hThread, INFINITE);
// Fill in the library handle
GetExitCodeThread(hThread, DWORD(lpRemote^.LibraryHandle));
// Add to list
result:=1;
finally
// Close the thread handle
CloseHandle(hThread);
end;
end;
finally
// Free allocated memory
VirtualFree(lpLibRemote, 0, MEM_RELEASE);
end;
end;
end;
finally
// Close the process handle
CloseHandle(hProcess);
end;
end;
end;
End; |
According to msdn if I declare PROCESS_VM_OPERATION it allows the use of WriteProcessMemory and it doesn't crash, my injector just throws an access violation error.
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25856 Location: The netherlands
|
Posted: Wed Feb 23, 2011 9:25 pm Post subject: |
|
|
the msdn on writeprocessmemory says :"The handle must have PROCESS_VM_WRITE and PROCESS_VM_OPERATION access to the process."
but again, what part is the access violation in? The target process or your app ?
anyhow, just set a breakpoint and step through the code to find out where it goes bad
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
Luig Cheater
Reputation: 0
Joined: 24 Sep 2010 Posts: 26
|
Posted: Sat Feb 26, 2011 12:44 am Post subject: |
|
|
Alright, I still can't get that function to work. The problem lies in writeprocessmemory. It just raises Access Violation. The interesting part is that this code:
| Code: | procedure InjectDll3(PID: dword; DLL: pChar);
var
BytesWritten, hProcess, hThread, TID: Cardinal;
Parameters: pointer;
pThreadStartRoutine: Pointer;
begin
hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
Parameters := VirtualAllocEx( hProcess, nil, Length(DLL), MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(hProcess,Parameters,DLL,Length(DLL),BytesWritten);
pThreadStartRoutine := GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryA');
hThread := CreateRemoteThread(hProcess, nil, 0, pThreadStartRoutine, Parameters, 0, BytesWritten);
CloseHandle(hProcess);
end; |
can actually write to the process but this one causes the target process to crash. I just need a simple function I can use to inject a .dll into a target process. If someone could provide one that works in Free Pascal, that would be truly appreciated.
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25856 Location: The netherlands
|
Posted: Sat Feb 26, 2011 6:46 am Post subject: |
|
|
ce's dll injection obviously works, but I make use of a slightly more fail proof injector using auto assembler
as for this code:
1: try replacing length(dll) with length(dll+1) so the 0 terminator is written as well, just in case the memory is not zero'd on alloc (weird, but might happen if you use a selfwritten alloc)
2: the dll you pass has the FULL path ?
3: you are sure your dll and target process are 32-bit right ?
4: If you inject your dll with ce into the target process, does it crash then as well ?
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
DeletedUser14087 I post too much
Reputation: 2
Joined: 21 Jun 2006 Posts: 3069
|
Posted: Sat Feb 26, 2011 10:26 am Post subject: |
|
|
| You need SeDebugPrivilege privilege enabled, this is known for Pascal / Delphi.
|
|
| Back to top |
|
 |
Luig Cheater
Reputation: 0
Joined: 24 Sep 2010 Posts: 26
|
Posted: Sat Feb 26, 2011 11:46 am Post subject: |
|
|
| I retrieved SEDebugPrivileges, tried the +1, I am sure both are 32 bit, I believe I am writing the whole path, I can inject just fine from AutoIt or CE. I still crash the target program when I use the function that can actually write to the memory. The other function still raises an exception at writeprocessmemory.
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25856 Location: The netherlands
|
Posted: Sat Feb 26, 2011 6:26 pm Post subject: |
|
|
in the first function step through and see if you can find out why. (sounds like a nil pointer)
debug that other function as well and CONFIRM that the path of the dll is valid
Actually, just add this code at the beginning:
| Code: |
if (not fileexists(dll)) or (pos(directoryseperator, dll)=0) then
raise exception.create('The dll path is wrong');
|
also, i see a lot of your code is based on C code (especially the first routine)
remember that in pascal strings do NOT require \\ for directory seperators. so : c:\bla\mydll.dll and NOT c:\\bla\\mydll.dll
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
Luig Cheater
Reputation: 0
Joined: 24 Sep 2010 Posts: 26
|
Posted: Sat Feb 26, 2011 6:46 pm Post subject: |
|
|
| I just did a showmessage(dll) and confirmed it passes the correct path. I've been trying to debug these functions to atleast get 1 of them to work. No such luck.
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|