Jako że zacząłem zabawę z Delphi i jako początkujący mam małą wiedze na temat programowania, ale wyskrobałem coś takiego z kilku źródeł z Internetu i działa to całkiem dobrze w systemach x86 i x64.
Problem pojawia się dopiero wtedy gdy próbuje pobrać i zapisać adres z pliku x64 który ma większy adres tzn nie potrafię zmusić tak program by zwracał wartość z dword(90000000) do qword(900090000000), a potem zsumował to prawidłowo z Offsetem by końcowy adres wyglądał tak 900090000200 i 900090000300.
library msimg32;
uses
Windows,
SysUtils,
PsAPI,
TlHelp32;
type
TOrgFuncs = record
case Integer of
0: (Base: FARPROC;);
1: (Arr: array [0..4] of FARPROC;);
end;
const
SIZE_OF_FUNC = SizeOf(FARPROC);
var
dwThrdHack: Dword = 0;
dwThrdMain: Dword = 0;
Patch: Boolean = True;
NewBytes: array of Byte;
hl: HINST;
OrgFuncs: TOrgFuncs;
InitialAddress : Cardinal;
Orgversion : HMODULE;
sysPath : string;
// Write Bytes to Address Method
Function WriteIt(pAddress: Pointer; Bytes: Array of Byte): Boolean;
var
dwProtect: DWord;
begin
//Change address Protecting to read/write/Execute and save the original in dwProtect
if VirtualProtect(pAddress, SizeOf(Bytes), PAGE_EXECUTE_READWRITE, @dwProtect) then
begin
//Write the new bytes to addres and the length of bytes to be written
Move(Bytes, pAddress^, Length(Bytes));
//Restore original Protecting to section we have just written to.
VirtualProtect(pAddress, SizeOf(Bytes), dwProtect, @dwProtect);
end;
end;
function FuncMain(const LPVOID: variant): Boolean;
Const
// Offset's
Offset_1 = $200;
Offset_2 = $300;
//Patches Bytes
Patch_1 : Array[0..3] of byte = ($90,$90,$90,$90);
Patch_2 : Array[0..3] of byte = ($90,$90,$90,$90);
begin
while (True) do
begin
//Write Patch
if Patch then
begin
WriteIt(ptr(Offset_1+InitialAddress),Patch_1); // Zawsze jest mov ecx, dword ptr ds:[0x00000000004449C0],
WriteIt(ptr(Offset_2+InitialAddress),Patch_2); //a powinno być mov rcx, qword ptr ds:[0x00000000004449C0]
break;
end;
end;
end;
function ProcessIDFromAppname ( appname: String ): DWORD;
var
snapshot: THandle;
processEntry : TProcessEntry32;
begin
Result := 0;
appName := UpperCase( appname );
snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0 );
If snapshot <> 0 Then
try
processEntry.dwSize := Sizeof( processEntry );
If Process32First( snapshot, processEntry ) Then
Repeat
If Pos(appname,
UpperCase(ExtractFilename(StrPas(processEntry.szExeFile)))) > 0
then begin
Result:= processEntry.th32ProcessID;
Break;
end; { If }
until not Process32Next( snapshot, processEntry );
finally
CloseHandle( snapshot );
end;
end;
function GetModuleBaseAddress(ProcessID: Cardinal; MName: String): Pointer;
var
Modules : Array of HMODULE;
cbNeeded, i : Cardinal;
ModuleInfo : TModuleInfo;
ModuleName : Array[0..MAX_PATH] of Char;
PHandle : THandle;
begin
Result := nil;
SetLength(Modules, 1024);
PHandle := OpenProcess(PROCESS_QUERY_INFORMATION + PROCESS_VM_READ, False, ProcessID);
if (PHandle <> 0) then
begin
EnumProcessModules(PHandle, @Modules[0], 1024 * SizeOf(HMODULE), cbNeeded);
SetLength(Modules, cbNeeded div SizeOf(HMODULE)); //Setting the number of modules
for i := 0 to Length(Modules) - 1 do //Start the bucle
begin
GetModuleBaseName(PHandle, Modules[i], ModuleName, SizeOf(ModuleName));
if AnsiCompareText(MName, ModuleName) = 0 then
begin
GetModuleInformation(PHandle, Modules[i], @ModuleInfo, SizeOf(ModuleInfo));
Result := ModuleInfo.lpBaseOfDll;
CloseHandle(PHandle);
Exit;
end;
end;
end;
end;
Function Initial_Address: Boolean;
var
Address, PID : Cardinal;
Buff : NativeUINT;
Value: Cardinal;
H: THandle;
begin
PID := ProcessIDFromAppname('Test.exe');
H := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,False,PID);
InitialAddress := dword(GetModuleBaseAddress(PID,'Test.exe'));
// Wynik końcowy zawsze jest mov dword ptr ds:[0x00000000004449C0],eax,
//a powinien być mov qword ptr ds:[0x00000000004449C0], rax
begin
//Modules exsist so we can return true
Result := True;
end;
end;
Function Thread(): Dword;
var
cHandle: Cardinal;
begin
//Call our function to check for loaded modules
Repeat
Sleep(20);
Until ((Initial_Address ) and (dwThrdMain = 0));
//Creat one thread and one for writting our patches(if = to true)
CreateThread(nil, 0, @FuncMain, nil, 0, dwThrdMain);
end;
function SystemDir: string;
var
WindowsDirectory: array[0..MAX_PATH] of Char;
begin
GetWindowsDirectory(WindowsDirectory, MAX_PATH - 1);
SetLength(Result, StrLen(WindowsDirectory));
Result := IncludeTrailingPathDelimiter(WindowsDirectory) + 'System32\';
end;
procedure DllMain(Reason: Integer);
begin
case Reason of
DLL_PROCESS_ATTACH:
begin
hl := LoadLibrary('msimg32.dll');
if hl = 0 then Exit;
OrgFuncs.Arr[0] := GetProcAddress(hl, 'vSetDdrawflag');
OrgFuncs.Arr[1] := GetProcAddress(hl, 'AlphaBlend');
OrgFuncs.Arr[2] := GetProcAddress(hl, 'DllInitialize');
OrgFuncs.Arr[3] := GetProcAddress(hl, 'GradientFill');
OrgFuncs.Arr[4] := GetProcAddress(hl, 'TransparentBlt');
CreateThread(nil, 0, @Thread, nil, 0, dwThrdHack);
end;
DLL_PROCESS_DETACH:
begin
FreeLibrary(hl);
end;
end;
end;
procedure E0();
asm
jmp [OrgFuncs.Base + SIZE_OF_FUNC * 0]
end;
procedure E1();
asm
jmp [OrgFuncs.Base + SIZE_OF_FUNC * 1]
end;
procedure E2();
asm
jmp [OrgFuncs.Base + SIZE_OF_FUNC * 2]
end;
procedure E3();
asm
jmp [OrgFuncs.Base + SIZE_OF_FUNC * 3]
end;
procedure E4();
asm
jmp [OrgFuncs.Base + SIZE_OF_FUNC * 4]
end;
exports
E0 index 1 name 'vSetDdrawflag',
E1 index 2 name 'AlphaBlend',
E2 index 3 name 'DllInitialize',
E3 index 4 name 'GradientFill',
E4 index 5 name 'TransparentBlt';
begin
DllProc := @DllMain;
DLLProc(DLL_PROCESS_ATTACH);
end.