el programa tiene 2 botones que inyecta 1 dll de forma estatica o como puntero "segun mi comprencion"
utiliza la unit afxCodeHook actualizada a delphi xe (nombre del autor enn la unit)
señor moderador ,no se donde estan las etiquetas de delphi corrija por favor.
nota:recien veo que tiene opcodes ,no recuerdo si el original era asi
ejecuten bajo su responsabilidad yo lo probe y no note nada raro
culaquier problema a papelera
saludos
programa
Código: Seleccionar todo
unit Unit1;
Código: Seleccionar todo
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,afxCodeHook;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{var
lpStartupInfo : STARTUPINFO;
lpProcessInformation : PROCESS_INFORMATION;
begin
lpStartupInfo := new STARTUPINFO();
lpProcessInformation := new PROCESS_INFORMATION();
Console.WriteLine('Creating Process');
CreateProcess('C:\WINDOWS\SYSTEM32\notepad.exe', nil, IntPtr.Zero, IntPtr.Zero,
false, 0, IntPtr.Zero, nil, var lpStartupInfo, out lpProcessInformation); }
procedure TForm1.Button1Click(Sender: TObject);
var
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
BytesRead, Module, Process, Size: dword;
Path: array [0..MAX_PATH] of char;
Data: pointer;
begin
//create process to inject into
ZeroMemory(@StartInfo, SizeOf(TStartupInfo));
StartInfo.cb := SizeOf(TStartupInfo);
CreateProcess('c:\windows\notepad.exe', nil, nil, nil, False, 0, nil, nil, StartInfo, ProcInfo);
//get the dll data to inject
Process := ProcInfo.hProcess;
Module := CreateFile(pchar('test.dll'), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
Size := GetFileSize(Module, nil);
GetMem(Data, Size);
ReadFile(Module, Data^, Size, BytesRead, nil);
CloseHandle(Module);
//inject the DLL using the Ex method
InjectLibrary2(Process, Data);
FreeMem(Data);
Sleep(3000);
//kill the process
TerminateProcess(Process, 0);
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Process: dword;
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
Path: array [0..MAX_PATH] of char;
begin
//create process to inject into
ZeroMemory(@StartInfo, SizeOf(TStartupInfo));
StartInfo.cb := SizeOf(TStartupInfo);
CreateProcess('c:\windows\notepad.exe',nil, nil, nil, False, 0, nil, nil, StartInfo, ProcInfo);
Sleep(100);
//inject the dll into the process
Process := ProcInfo.hProcess;
InjectLibrary1(Process, 'test.dll');
Sleep(3000);
//kill the process
//TerminateProcess(Process, 0);
end;
end.
unit afxCodeHook
{
Delphi Hooking Library by Aphex
Delphi XE, XE2, XE3 Support added by imsh
}
unit afxCodeHook;
{$IMAGEBASE $13140000}
interface
uses
Windows;
function SizeOfCode(Code: pointer): dword;
function SizeOfProc(Proc: pointer): dword;
function InjectString(Process: NativeUInt; Text: PAnsiChar): PAnsiChar;
function InjectMemory(Process: NativeUInt; Memory: pointer; Len: dword): pointer;
function InjectThread(Process: NativeUInt; Thread: pointer; Info: pointer; InfoLen: dword; Results: boolean): THandle;
function InjectLibrary1(Process: NativeUInt; ModulePath: PAnsiChar): boolean; overload;
function InjectLibrary2(Process: NativeUInt; Src: pointer): boolean; overload;
function InjectExe(Process: NativeUInt; EntryPoint: pointer): boolean;
function UninjectLibrary(Process: NativeUInt; ModulePath: PAnsiChar): boolean;
function CreateProcessEx(lpApplicationName: PAnsiChar; lpCommandLine: PAnsiChar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory: PAnsiChar; const lpStartupInfo: TStartupInfoA; var lpProcessInformation: TProcessInformation; ModulePath: PAnsiChar): boolean; overload;
function CreateProcessEx(lpApplicationName: PAnsiChar; lpCommandLine: PAnsiChar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory: PAnsiChar; const lpStartupInfo: TStartupInfoA; var lpProcessInformation: TProcessInformation; Src: pointer): boolean; overload;
function HookCode(TargetProc, NewProc: pointer; var OldProc: pointer): boolean;
function UnhookCode(OldProc: pointer): boolean;
function DeleteFileEx(FilePath: PAnsiChar): boolean;
function DisableSFC: boolean;
implementation
type
TModuleList = array of cardinal;
PImageImportDescriptor = ^TImageImportDescriptor;
TImageImportDescriptor = packed record
OriginalFirstThunk: longword;
TimeDateStamp: longword;
ForwarderChain: longword;
Name: longword;
FirstThunk: longword;
end;
PImageBaseRelocation = ^TImageBaseRelocation;
TImageBaseRelocation = packed record
VirtualAddress: cardinal;
SizeOfBlock: cardinal;
end;
TDllEntryProc = function(hinstDLL: HMODULE; dwReason: longword; lpvReserved: pointer): boolean; stdcall;
TStringArray = array of string;
TLibInfo = record
ImageBase: pointer;
ImageSize: longint;
DllProc: TDllEntryProc;
DllProcAddress: pointer;
LibsUsed: TStringArray;
end;
PLibInfo = ^TLibInfo;
Ppointer = ^pointer;
TSections = array [0..0] of TImageSectionHeader;
const
IMPORTED_NAME_OFFSET = $00000002;
IMAGE_ORDINAL_FLAG32 = $80000000;
IMAGE_ORDINAL_MASK32 = $0000FFFF;
Opcodes1: array [0..255] of word =
(
(16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),
(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),
(17124),(8209),(8420),(33793),(35906),(0),(32768),(16913),(17124),(8209),(8420),(33793),(35906),(0),(32768),(16913),
(17124),(8209),(8420),(33793),(35906),(0),(32768),(529),(740),(17),(228),(1025),(3138),(0),(32768),(24645),
(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(69),
(69),(69),(69),(69),(69),(69),(69),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(0),
(32768),(228),(16922),(0),(0),(0),(0),(3072),(11492),(1024),(9444),(0),(0),(0),(0),(5120),
(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(1296),
(3488),(1296),(1440),(529),(740),(41489),(41700),(16913),(17124),(8209),(8420),(17123),(8420),(227),(416),(0),
(57414),(57414),(57414),(57414),(57414),(57414),(57414),(32768),(0),(0),(0),(0),(0),(0),(32768),(33025),
(33090),(769),(834),(0),(0),(0),(0),(1025),(3138),(0),(0),(32768),(32768),(0),(0),(25604),
(25604),(25604),(25604),(25604),(25604),(25604),(25604),(27717),(27717),(27717),(27717),(27717),(27717),(27717),(27717),(17680),
(17824),(2048),(0),(8420),(8420),(17680),(19872),(0),(0),(2048),(0),(0),(1024),(0),(0),(16656),
(16800),(16656),(16800),(33792),(33792),(0),(32768),(8),(8),(8),(8),(8),(8),(8),(8),(5120),
(5120),(5120),(5120),(33793),(33858),(1537),(1602),(7168),(7168),(0),(5120),(32775),(32839),(519),(583),(0),
(0),(0),(0),(0),(0),(8),(8),(0),(0),(0),(0),(0),(0),(16656),(416)
);
Opcodes2: array [0..255] of word =
(
(280),(288),(8420),(8420),(65535),(0),(0),(0),(0),(0),(65535),(65535),(65535),(272),(0),(1325),(63),
(575),(63),(575),(63),(63),(63),(575),(272),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(16419),
(16419),(547),(547),(65535),(65535),(65535),(65535),(63),(575),(47),(575),(61),(61),(63),(63),(0),
(32768),(32768),(32768),(0),(0),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(8420),
(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(16935),
(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(237),
(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(101),(237),(1261),
(1192),(1192),(1192),(237),(237),(237),(0),(65535),(65535),(65535),(65535),(65535),(65535),(613),(749),(7168),
(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(16656),
(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(0),
(0),(32768),(740),(18404),(17380),(49681),(49892),(0),(0),(0),(17124),(18404),(17380),(32),(8420),(49681),
(49892),(8420),(17124),(8420),(8932),(8532),(8476),(65535),(65535),(1440),(17124),(8420),(8420),(8532),(8476),(41489),
(41700),(1087),(548),(1125),(9388),(1087),(33064),(24581),(24581),(24581),(24581),(24581),(24581),(24581),(24581),(65535),
(237),(237),(237),(237),(237),(749),(8364),(237),(237),(237),(237),(237),(237),(237),(237),(237),
(237),(237),(237),(237),(237),(63),(749),(237),(237),(237),(237),(237),(237),(237),(237),(65535),
(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(0)
);
Opcodes3: array [0..9] of array [0..15] of word =
(
((1296),(65535),(16656),(16656),(33040),(33040),(33040),(33040),(1296),(65535),(16656),(16656),(33040),(33040),(33040),(33040)),
((3488),(65535),(16800),(16800),(33184),(33184),(33184),(33184),(3488),(65535),(16800),(16800),(33184),(33184),(33184),(33184)),
((288),(288),(288),(288),(288),(288),(288),(288),(54),(54),(48),(48),(54),(54),(54),(54)),
((288),(65535),(288),(288),(272),(280),(272),(280),(48),(48),(0),(48),(0),(0),(0),(0)),
((288),(288),(288),(288),(288),(288),(288),(288),(54),(54),(54),(54),(65535),(0),(65535),(65535)),
((288),(65535),(288),(288),(65535),(304),(65535),(304),(54),(54),(54),(54),(0),(54),(54),(0)),
((296),(296),(296),(296),(296),(296),(296),(296),(566),(566),(48),(48),(566),(566),(566),(566)),
((296),(65535),(296),(296),(272),(65535),(272),(280),(48),(48),(48),(48),(48),(48),(65535),(65535)),
((280),(280),(280),(280),(280),(280),(280),(280),(566),(566),(48),(566),(566),(566),(566),(566)),
((280),(65535),(280),(280),(304),(296),(304),(296),(48),(48),(48),(48),(0),(54),(54),(65535))
);
function SaveOldFunction(Proc: pointer; Old: pointer): longword; forward;
function GetProcAddressEx(Process: LongWord; lpModuleName, lpProcName: PAnsiChar; dwProcLen: dword): pointer; forward;
function MapLibrary(Process: LongWord; Dest, Src: pointer): TLibInfo; forward;
function SizeOfCode(Code: pointer): longword;
var
Opcode: word;
Modrm: byte;
Fixed, AddressOveride: boolean;
Last, OperandOveride, Flags, Rm, Size, Extend: longword;
begin
try
Last := longword(Code);
if Code <> nil then
begin
AddressOveride := False;
Fixed := False;
OperandOveride := 4;
Extend := 0;
repeat
Opcode := byte(Code^);
Code := pointer(longword(Code) + 1);
if Opcode = $66 then
begin
OperandOveride := 2;
end
else if Opcode = $67 then
begin
AddressOveride := True;
end
else
begin
if not ((Opcode and $E7) = $26) then
begin
if not (Opcode in [$64..$65]) then
begin
Fixed := True;
end;
end;
end;
until Fixed;
if Opcode = $0f then
begin
Opcode := byte(Code^);
Flags := Opcodes2[Opcode];
Opcode := Opcode + $0f00;
Code := pointer(longword(Code) + 1);
end
else
begin
Flags := Opcodes1[Opcode];
end;
if ((Flags and $0038) <> 0) then
begin
Modrm := byte(Code^);
Rm := Modrm and $7;
Code := pointer(longword(Code) + 1);
case (Modrm and $c0) of
$40: Size := 1;
$80:
begin
if AddressOveride then
begin
Size := 2;
end
else
Size := 4;
end;
else
begin
Size := 0;
end;
end;
if not (((Modrm and $c0) <> $c0) and AddressOveride) then
begin
if (Rm = 4) and ((Modrm and $c0) <> $c0) then
begin
Rm := byte(Code^) and $7;
end;
if ((Modrm and $c0 = 0) and (Rm = 5)) then
begin
Size := 4;
end;
Code := pointer(longword(Code) + Size);
end;
if ((Flags and $0038) = $0008) then
begin
case Opcode of
$f6: Extend := 0;
$f7: Extend := 1;
$d8: Extend := 2;
$d9: Extend := 3;
$da: Extend := 4;
$db: Extend := 5;
$dc: Extend := 6;
$dd: Extend := 7;
$de: Extend := 8;
$df: Extend := 9;
end;
if ((Modrm and $c0) <> $c0) then
begin
Flags := Opcodes3[Extend][(Modrm shr 3) and $7];
end
else
begin
Flags := Opcodes3[Extend][((Modrm shr 3) and $7) + 8];
end;
end;
end;
case (Flags and $0C00) of
$0400: Code := pointer(longword(Code) + 1);
$0800: Code := pointer(longword(Code) + 2);
$0C00: Code := pointer(longword(Code) + OperandOveride);
else
begin
case Opcode of
$9a, $ea: Code := pointer(longword(Code) + OperandOveride + 2);
$c8: Code := pointer(longword(Code) + 3);
$a0..$a3:
begin
if AddressOveride then
begin
Code := pointer(longword(Code) + 2)
end
else
begin
Code := pointer(longword(Code) + 4);
end;
end;
end;
end;
end;
end;
Result := longword(Code) - Last;
except
Result := 0;
end;
end;
function SizeOfProc(Proc: pointer): longword;
var
Length: longword;
begin
Result := 0;
repeat
Length := SizeOfCode(Proc);
Inc(Result, Length);
if ((Length = 1) and (byte(Proc^) = $C3)) then Break;
Proc := pointer(longword(Proc) + Length);
until Length = 0;
end;
function InjectString(Process: NativeUInt; Text: PAnsiChar): PAnsiChar;
var
BytesWritten,
Old, Size: NativeUInt;
begin
Size := Length(Text) + 1;
Result := VirtualAllocEx(Process, nil, Size, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
VirtualProtectEx(Process, Result, Size, PAGE_EXECUTE_READWRITE, @Old);
WriteProcessMemory(Process, Result, Text, Size, BytesWritten);
end;
function InjectMemory(Process: NativeUInt; Memory: pointer; Len: longword): pointer;
var
BytesWritten: NativeUInt;
begin
Result := VirtualAllocEx(Process, nil, Len, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(Process, Result, Memory, Len, BytesWritten);
end;
function InjectThread(Process: NativeUInt; Thread: pointer; Info: pointer; InfoLen: longword; Results: boolean): THandle;
var
pThread, pInfo: pointer;
BytesRead: NativeUInt;
TID: Cardinal;
begin
pInfo := InjectMemory(Process, Info, InfoLen);
pThread := InjectMemory(Process, Thread, SizeOfProc(Thread));
Result := CreateRemoteThread(Process, nil, 0, pThread, pInfo, 0, TID);
if Results then
begin
WaitForSingleObject(Result, INFINITE);
ReadProcessMemory(Process, pInfo, Info, InfoLen, BytesRead);
end;
end;
function InjectLibrary1(Process: NativeUInt; ModulePath: PAnsiChar): boolean;
type
TInjectLibraryInfo = record
pLoadLibrary: pointer;
lpModuleName: pointer;
pSleep: pointer;
end;
var
InjectLibraryInfo: TInjectLibraryInfo;
Thread: THandle;
procedure InjectLibraryThread(lpParameter: pointer); stdcall;
var
InjectLibraryInfo: TInjectLibraryInfo;
begin
InjectLibraryInfo := TInjectLibraryInfo(lpParameter^);
asm
push InjectLibraryInfo.lpModuleName
call InjectLibraryInfo.pLoadLibrary
@noret:
mov eax, $FFFFFFFF
push eax
call InjectLibraryInfo.pSleep
jmp @noret
end;
end;
begin
Result := False;
InjectLibraryInfo.pSleep := GetProcAddress(GetModuleHandle('kernel32'), 'Sleep');
InjectLibraryInfo.pLoadLibrary := GetProcAddress(GetModuleHandle('kernel32'), 'LoadLibraryA');
InjectLibraryInfo.lpModuleName := InjectString(Process, PAnsiChar(ModulePath));
Thread := InjectThread(Process, @InjectLibraryThread, @InjectLibraryInfo, SizeOf(TInjectLibraryInfo), False);
if Thread = 0 then Exit;
CloseHandle(Thread);
Result := True;
Sleep(100);
end;
function InjectLibrary2(Process: NativeUInt; Src: pointer): boolean;
type
TDllLoadInfo = record
Module: pointer;
EntryPoint: pointer;
end;
var
Lib: TLibInfo;
DllLoadInfo: TDllLoadInfo;
BytesWritten: NativeUInt;
ImageNtHeaders: PImageNtHeaders;
pModule: pointer;
Offset: longword;
procedure DllEntryPoint(lpParameter: pointer); stdcall;
var
LoadInfo: TDllLoadInfo;
begin
LoadInfo := TDllLoadInfo(lpParameter^);
asm
xor eax, eax
push eax
push DLL_PROCESS_ATTACH
push LoadInfo.Module
call LoadInfo.EntryPoint
end;
end;
begin
Result := False;
ImageNtHeaders := pointer(int64(cardinal(Src)) + PImageDosHeader(Src)._lfanew);
Offset := $10000000;
repeat
Inc(Offset, $10000);
pModule := VirtualAlloc(pointer(ImageNtHeaders.OptionalHeader.ImageBase + Offset), ImageNtHeaders.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if pModule <> nil then
begin
VirtualFree(pModule, 0, MEM_RELEASE);
pModule := VirtualAllocEx(Process, pointer(ImageNtHeaders.OptionalHeader.ImageBase + Offset), ImageNtHeaders.OptionalHeader.SizeOfImage, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
end;
until ((pModule <> nil) or (Offset > $30000000));
Lib := MapLibrary(Process, pModule, Src);
if Lib.ImageBase = nil then Exit;
DllLoadInfo.Module := Lib.ImageBase;
DllLoadInfo.EntryPoint := Lib.DllProcAddress;
WriteProcessMemory(Process, pModule, Lib.ImageBase, Lib.ImageSize, BytesWritten);
if InjectThread(Process, @DllEntryPoint, @DllLoadInfo, SizeOf(TDllLoadInfo), False) <> 0 then Result := True
end;
function InjectExe(Process: NativeUInt; EntryPoint: pointer): boolean;
var
Module, NewModule: pointer;
Size: NativeUInt;
TID: Cardinal;
begin
Result := False;
Module := pointer(GetModuleHandle(nil));
Size := PImageOptionalHeader32(pointer(integer(Module) + PImageDosHeader(Module)._lfanew + SizeOf(longword) + SizeOf(TImageFileHeader))).SizeOfImage;
VirtualFreeEx(Process, Module, 0, MEM_RELEASE);
NewModule := InjectMemory(Process, Module, Size);
if CreateRemoteThread(Process, nil, 0, EntryPoint, NewModule, 0, TID) <> 0 then Result := True;
end;
function UninjectLibrary(Process: NativeUInt; ModulePath: PAnsiChar): boolean;
type
TUninjectLibraryInfo = record
pFreeLibrary: pointer;
pGetModuleHandle: pointer;
lpModuleName: pointer;
pExitThread: pointer;
end;
var
UninjectLibraryInfo: TUninjectLibraryInfo;
Thread: THandle;
procedure UninjectLibraryThread(lpParameter: pointer); stdcall;
var
UninjectLibraryInfo: TUninjectLibraryInfo;
begin
UninjectLibraryInfo := TUninjectLibraryInfo(lpParameter^);
asm
@1:
inc ecx
push UninjectLibraryInfo.lpModuleName
call UninjectLibraryInfo.pGetModuleHandle
cmp eax, 0
je @2
push eax
call UninjectLibraryInfo.pFreeLibrary
jmp @1
@2:
push eax
call UninjectLibraryInfo.pExitThread
end;
end;
begin
Result := False;
UninjectLibraryInfo.pGetModuleHandle := GetProcAddress(GetModuleHandleA('kernel32'), 'GetModuleHandleA');
UninjectLibraryInfo.pFreeLibrary := GetProcAddress(GetModuleHandleA('kernel32'), 'FreeLibrary');
UninjectLibraryInfo.pExitThread := GetProcAddress(GetModuleHandleA('kernel32'), 'ExitThread');
UninjectLibraryInfo.lpModuleName := InjectString(Process, PAnsiChar(ModulePath));
Thread := InjectThread(Process, @UninjectLibraryThread, @UninjectLibraryInfo, SizeOf(TUninjectLibraryInfo), False);
if Thread = 0 then Exit;
CloseHandle(Thread);
Result := True;
end;
function CreateProcessEx(lpApplicationName: PAnsiChar; lpCommandLine: PAnsiChar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory: PAnsiChar; const lpStartupInfo: TStartupInfoA; var lpProcessInformation: TProcessInformation; ModulePath: PAnsiChar): boolean;
begin
Result := False;
if not CreateProcessA(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags or CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation) then Exit;
Result := InjectLibrary1(lpProcessInformation.hProcess, ModulePath);
ResumeThread(lpProcessInformation.hThread);
end;
function CreateProcessEx(lpApplicationName: PAnsiChar; lpCommandLine: PAnsiChar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory: PAnsiChar; const lpStartupInfo: TStartupInfoA; var lpProcessInformation: TProcessInformation; Src: pointer): boolean;
begin
Result := False;
if not CreateProcessA(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags or CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation) then Exit;
Result := InjectLibrary2(lpProcessInformation.hProcess, Src);
ResumeThread(lpProcessInformation.hThread);
end;
function HookCode(TargetProc, NewProc: pointer; var OldProc: pointer): boolean;
var
Address: longword;
OldProtect: longword;
OldFunction: pointer;
Proc: pointer;
begin
Result := False;
try
Proc := TargetProc;
Address := longword(NewProc) - longword(Proc) - 5;
VirtualProtect(Proc, 5, PAGE_EXECUTE_READWRITE, OldProtect);
GetMem(OldFunction, 255);
longword(OldFunction^) := longword(Proc);
byte(pointer(longword(OldFunction) + 4)^) := SaveOldFunction(Proc, pointer(longword(OldFunction) + 5));
byte(pointer(Proc)^) := $e9;
longword(pointer(longword(Proc) + 1)^) := Address;
VirtualProtect(Proc, 5, OldProtect, OldProtect);
OldProc := pointer(longword(OldFunction) + 5);
except
Exit;
end;
Result := True;
end;
function UnhookCode(OldProc: pointer): boolean;
var
OldProtect: longword;
Proc: pointer;
SaveSize: longword;
begin
Result := True;
try
Proc := pointer(longword(pointer(longword(OldProc) - 5)^));
SaveSize := byte(pointer(longword(OldProc) - 1)^);
VirtualProtect(Proc, 5, PAGE_EXECUTE_READWRITE, OldProtect);
CopyMemory(Proc, OldProc, SaveSize);
VirtualProtect(Proc, 5, OldProtect, OldProtect);
FreeMem(pointer(longword(OldProc) - 5));
except
Result := False;
end;
end;
function DeleteFileEx(FilePath: PAnsiChar): boolean;
type
TDeleteFileExInfo = record
pSleep: pointer;
lpModuleName: pointer;
pDeleteFile: pointer;
pExitThread: pointer;
end;
var
DeleteFileExInfo: TDeleteFileExInfo;
Thread: THandle;
Process: longword;
PID: longword;
procedure DeleteFileExThread(lpParameter: pointer); stdcall;
var
DeleteFileExInfo: TDeleteFileExInfo;
begin
DeleteFileExInfo := TDeleteFileExInfo(lpParameter^);
asm
@1:
push 1000
call DeleteFileExInfo.pSleep
push DeleteFileExInfo.lpModuleName
call DeleteFileExInfo.pDeleteFile
cmp eax, 0
je @1
push eax
call DeleteFileExInfo.pExitThread
end;
end;
begin
Result := False;
GetWindowThreadProcessID(FindWindowA('Shell_TrayWnd', nil), @PID);
Process := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
DeleteFileExInfo.pSleep := GetProcAddress(GetModuleHandleA('kernel32'), 'Sleep');
DeleteFileExInfo.pDeleteFile := GetProcAddress(GetModuleHandleA('kernel32'), 'DeleteFileA');
DeleteFileExInfo.pExitThread := GetProcAddress(GetModuleHandleA('kernel32'), 'ExitThread');
DeleteFileExInfo.lpModuleName := InjectString(Process, FilePath);
Thread := InjectThread(Process, @DeleteFileExThread, @DeleteFileExInfo, SizeOf(TDeleteFileExInfo), False);
if Thread = 0 then Exit;
CloseHandle(Thread);
CloseHandle(Process);
Result := True;
end;
function DisableSFC: boolean;
var
Process, SFC, PID, Thread, ThreadID: longword;
begin
Result := False;
SFC := LoadLibrary('sfc.dll');
GetWindowThreadProcessID(FindWindowA('NDDEAgnt', nil), @PID);
Process := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
Thread := CreateRemoteThread(Process, nil, 0, GetProcAddress(SFC, PAnsiChar(2 and $ffff)), nil, 0, ThreadId);
if Thread = 0 then Exit;
CloseHandle(Thread);
CloseHandle(Process);
FreeLibrary(SFC);
Result := True;
end;
function SaveOldFunction(Proc: pointer; Old: pointer): longword;
var
SaveSize, Size: longword;
Next: pointer;
begin
SaveSize := 0;
Next := Proc;
while SaveSize < 5 do
begin
Size := SizeOfCode(Next);
Next := pointer(longword(Next) + Size);
Inc(SaveSize, Size);
end;
CopyMemory(Old, Proc, SaveSize);
byte(pointer(longword(Old) + SaveSize)^) := $e9;
longword(pointer(longword(Old) + SaveSize + 1)^) := longword(Next) - longword(Old) - SaveSize - 5;
Result := SaveSize;
end;
function GetProcAddressEx(Process: LongWord; lpModuleName, lpProcName: PAnsiChar; dwProcLen: dword): pointer;
type
TGetProcAddrExInfo = record
pExitThread: pointer;
pGetProcAddress: pointer;
pGetModuleHandle: pointer;
lpModuleName: pointer;
lpProcName: pointer;
end;
var
GetProcAddrExInfo: TGetProcAddrExInfo;
ExitCode: longword;
Thread: THandle;
procedure GetProcAddrExThread(lpParameter: pointer); stdcall;
var
GetProcAddrExInfo: TGetProcAddrExInfo;
begin
GetProcAddrExInfo := TGetProcAddrExInfo(lpParameter^);
asm
push GetProcAddrExInfo.lpModuleName
call GetProcAddrExInfo.pGetModuleHandle
push GetProcAddrExInfo.lpProcName
push eax
call GetProcAddrExInfo.pGetProcAddress
push eax
call GetProcAddrExInfo.pExitThread
end;
end;
begin
Result := nil;
GetProcAddrExInfo.pGetModuleHandle := GetProcAddress(GetModuleHandleA('kernel32'), 'GetModuleHandleA');
GetProcAddrExInfo.pGetProcAddress := GetProcAddress(GetModuleHandleA('kernel32'), 'GetProcAddress');
GetProcAddrExInfo.pExitThread := GetProcAddress(GetModuleHandleA('kernel32'), 'ExitThread');
if dwProcLen = 4 then
begin
GetProcAddrExInfo.lpProcName := lpProcName;
end
else
begin
GetProcAddrExInfo.lpProcName := InjectMemory(Process, lpProcName, dwProcLen);
end;
GetProcAddrExInfo.lpModuleName := InjectString(Process, lpModuleName);
Thread := InjectThread(Process, @GetProcAddrExThread, @GetProcAddrExInfo, SizeOf(GetProcAddrExInfo), False);
if Thread <> 0 then
begin
WaitForSingleObject(Thread, INFINITE);
GetExitCodeThread(Thread, ExitCode);
Result := pointer(ExitCode);
end;
end;
function MapLibrary(Process: LongWord; Dest, Src: pointer): TLibInfo;
var
ImageBase: pointer;
ImageBaseDelta: integer;
ImageNtHeaders: PImageNtHeaders;
PSections: ^TSections;
SectionLoop: integer;
SectionBase: pointer;
VirtualSectionSize, RawSectionSize: cardinal;
OldProtect: cardinal;
NewLibInfo: TLibInfo;
function StrToInt(S: string): integer;
begin
Val(S, Result, Result);
end;
procedure Add(Strings: TStringArray; Text: string);
begin
SetLength(Strings, Length(Strings) + 1);
Strings[Length(Strings) - 1] := Text;
end;
function Find(Strings: array of string; Text: string; var Index: integer): boolean;
var
StringLoop: integer;
begin
Result := False;
for StringLoop := 0 to Length(Strings) - 1 do
begin
if lstrcmpia(PAnsiChar(Strings[StringLoop]), PAnsiChar(Text)) = 0 then
begin
Index := StringLoop;
Result := True;
end;
end;
end;
function GetSectionProtection(ImageScn: cardinal): cardinal;
begin
Result := 0;
if (ImageScn and IMAGE_SCN_MEM_NOT_CACHED) <> 0 then
begin
Result := Result or PAGE_NOCACHE;
end;
if (ImageScn and IMAGE_SCN_MEM_EXECUTE) <> 0 then
begin
if (ImageScn and IMAGE_SCN_MEM_READ)<> 0 then
begin
if (ImageScn and IMAGE_SCN_MEM_WRITE)<> 0 then
begin
Result := Result or PAGE_EXECUTE_READWRITE
end
else
begin
Result := Result or PAGE_EXECUTE_READ
end;
end
else if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then
begin
Result := Result or PAGE_EXECUTE_WRITECOPY
end
else
begin
Result := Result or PAGE_EXECUTE
end;
end
else if (ImageScn and IMAGE_SCN_MEM_READ)<> 0 then
begin
if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then
begin
Result := Result or PAGE_READWRITE
end
else
begin
Result := Result or PAGE_READONLY
end
end
else if (ImageScn and IMAGE_SCN_MEM_WRITE) <> 0 then
begin
Result := Result or PAGE_WRITECOPY
end
else
begin
Result := Result or PAGE_NOACCESS;
end;
end;
procedure ProcessRelocs(PRelocs:PImageBaseRelocation);
var
PReloc: PImageBaseRelocation;
RelocsSize: cardinal;
Reloc: PWord;
ModCount: cardinal;
RelocLoop: cardinal;
begin
PReloc := PRelocs;
RelocsSize := ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
while cardinal(PReloc) - cardinal(PRelocs) < RelocsSize do
begin
ModCount := (PReloc.SizeOfBlock - Sizeof(PReloc^)) div 2;
Reloc := pointer(cardinal(PReloc) + sizeof(PReloc^));
for RelocLoop := 0 to ModCount - 1 do
begin
if Reloc^ and $f000 <> 0 then Inc(plongword(cardinal(ImageBase) + PReloc.VirtualAddress + (Reloc^ and $0fff))^, ImageBaseDelta);
Inc(Reloc);
end;
PReloc := pointer(Reloc);
end;
end;
procedure ProcessImports(PImports: PImageImportDescriptor);
var
PImport: PImageImportDescriptor;
Import: plongword;
PImportedName: PAnsiChar;
ProcAddress: pointer;
PLibName: PAnsiChar;
ImportLoop: integer;
function IsImportByOrdinal(ImportDescriptor: longword): boolean;
begin
Result := (ImportDescriptor and IMAGE_ORDINAL_FLAG32) <> 0;
end;
begin
PImport := PImports;
while PImport.Name <> 0 do
begin
PLibName := PAnsiChar(cardinal(PImport.Name) + cardinal(ImageBase));
if not Find(NewLibInfo.LibsUsed, PLibName, ImportLoop) then
begin
//Temp InjectLibrary1(Process, string(PLibName));
InjectLibrary1(Process, PLibName);
Add(NewLibInfo.LibsUsed, PLibName);
end;
if PImport.TimeDateStamp = 0 then
begin
Import := plongword(pImport.FirstThunk + cardinal(ImageBase))
end
else
begin
Import := plongword(pImport.OriginalFirstThunk + cardinal(ImageBase));
end;
while Import^ <> 0 do
begin
if IsImportByOrdinal(Import^) then
begin
ProcAddress := GetProcAddressEx(Process, PLibName, PAnsiChar(Import^ and $ffff), 4);
end
else
begin
PImportedName := PAnsiChar(Import^ + cardinal(ImageBase) + IMPORTED_NAME_OFFSET);
ProcAddress := GetProcAddressEx(Process, PLibName, PImportedName, Length(PImportedName));
end;
Ppointer(Import)^ := ProcAddress;
Inc(Import);
end;
Inc(PImport);
end;
end;
begin
ImageNtHeaders := pointer(int64(cardinal(Src)) + PImageDosHeader(Src)._lfanew);
ImageBase := VirtualAlloc(Dest, ImageNtHeaders.OptionalHeader.SizeOfImage, MEM_RESERVE, PAGE_NOACCESS);
ImageBaseDelta := cardinal(ImageBase) - ImageNtHeaders.OptionalHeader.ImageBase;
SectionBase := VirtualAlloc(ImageBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders, MEM_COMMIT, PAGE_READWRITE);
Move(Src^, SectionBase^, ImageNtHeaders.OptionalHeader.SizeOfHeaders);
VirtualProtect(SectionBase, ImageNtHeaders.OptionalHeader.SizeOfHeaders, PAGE_READONLY, OldProtect);
PSections := pointer(PAnsiChar(@(ImageNtHeaders.OptionalHeader)) + ImageNtHeaders.FileHeader.SizeOfOptionalHeader);
for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
begin
VirtualSectionSize := PSections[SectionLoop].Misc.VirtualSize;
RawSectionSize := PSections[SectionLoop].SizeOfRawData;
if VirtualSectionSize < RawSectionSize then
begin
VirtualSectionSize := VirtualSectionSize xor RawSectionSize;
RawSectionSize := VirtualSectionSize xor RawSectionSize;
VirtualSectionSize := VirtualSectionSize xor RawSectionSize;
end;
SectionBase := VirtualAlloc(PSections[SectionLoop].VirtualAddress + PAnsiChar(ImageBase), VirtualSectionSize, MEM_COMMIT, PAGE_READWRITE);
FillChar(SectionBase^, VirtualSectionSize, 0);
Move((PAnsiChar(src) + PSections[SectionLoop].pointerToRawData)^, SectionBase^, RawSectionSize);
end;
NewLibInfo.DllProc := TDllEntryProc(ImageNtHeaders.OptionalHeader.AddressOfEntryPoint + cardinal(ImageBase));
NewLibInfo.DllProcAddress := pointer(ImageNtHeaders.OptionalHeader.AddressOfEntryPoint + cardinal(ImageBase));
NewLibInfo.ImageBase := ImageBase;
NewLibInfo.ImageSize := ImageNtHeaders.OptionalHeader.SizeOfImage;
SetLength(NewLibInfo.LibsUsed, 0);
if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress <> 0 then ProcessRelocs(pointer(ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress + cardinal(ImageBase)));
if ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress <> 0 then ProcessImports(pointer(ImageNtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + cardinal(ImageBase)));
for SectionLoop := 0 to ImageNtHeaders.FileHeader.NumberOfSections - 1 do
begin
VirtualProtect(PSections[SectionLoop].VirtualAddress + PAnsiChar(ImageBase), PSections[SectionLoop].Misc.VirtualSize, GetSectionProtection(PSections[SectionLoop].Characteristics), OldProtect);
end;
Result := NewLibInfo;
end;
end.