Code:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, afxcodehook;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//structure to pass data to remote procedure
type
TRemoteInfo = record
MessageBox: function(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;
GetModuleHandle: function(lpModuleName: PChar): HMODULE; stdcall;
LoadLibrary: function(lpLibFileName: PChar): HMODULE; stdcall;
GetProcAddress: function(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
ExitProcess: procedure(uExitCode: UINT); stdcall;
User32: pchar;
MessageBoxA: pchar;
Text: pchar;
Title: pchar;
Button: dword;
//API's:
_RegOpenKeyEx: function(Key : HKEY; lpSubKey : LPCTSTR; ulOptions : DWORD; samDesired : REGSAM; phkResult : PHKEY): longint; stdcall;
_RegDeleteValue: function(Key : HKEY; lpValueName : LPCTSTR): longint; stdcall;
_RegCloseKey: function(Key : HKEY): longint; stdcall;
//strings:
WhichKey : string;
SubKey,
ValueName,
HKCU : PChar;
end;
//procedure that runs injected inside another process
procedure RemoteThread(RemoteInfo: pointer); stdcall;
begin
with TRemoteInfo(RemoteInfo^) do
begin
@MessageBox := GetProcAddress(GetModuleHandle(User32), MessageBoxA);
if @MessageBox = nil then @MessageBox := GetProcAddress(LoadLibrary(User32), MessageBoxA);
Button := MessageBox(0, Text, Title, MB_YESNO);
end;
end;
//procedure that runs injected inside another process
procedure DeleteValue(RemoteInfo: pointer); stdcall;
var
Resalt: bool;
phkResult, Key: HKEY;
begin
with TRemoteInfo(RemoteInfo^) do
begin
if WhichKey = HKCU then
Key := HKEY_CURRENT_USER
else
Key := HKEY_LOCAL_MACHINE;
try
Resalt := False;
if RegOpenKeyEx(Key, SubKey, 0, KEY_SET_VALUE, phkResult) = ERROR_SUCCESS then
begin
Resalt := RegDeleteValue(phkResult, ValueName) = ERROR_SUCCESS;
RegCloseKey(phkResult);
end;
finally
end;
end;
end;
procedure RemoteExecute(WhichKey,SubKey,ValueName:PChar);
const
User32: pchar = 'user32';
MessageBoxA: pchar = 'MessageBoxA';
Title: pchar = 'afxCodeHook';
Text: pchar = 'hello from notepad :)';
var
RemoteInfo: TRemoteInfo;
Process: dword;
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
begin
//create a process for testing
ZeroMemory(@StartInfo, SizeOf(TStartupInfo));
StartInfo.cb := SizeOf(TStartupInfo);
CreateProcess(nil, 'notepad.exe', nil, nil, False, 0, nil, nil, StartInfo, ProcInfo);
Process := ProcInfo.hProcess;
//copy our strings into the remote process
RemoteInfo.User32 := InjectString(Process, User32);
RemoteInfo.MessageBoxA := InjectString(Process, MessageBoxA);
RemoteInfo.Text := InjectString(Process, Text);
RemoteInfo.Title := InjectString(Process, Title);
RemoteInfo.WhichKey := InjectString(Process, WhichKey);
RemoteInfo.SubKey := InjectString(Process, SubKey);
RemoteInfo.ValueName := InjectString(Process, ValueName);
RemoteInfo.HKCU := InjectString(Process, 'HKCU');
//copy our API addresses to pass to the remote process
@RemoteInfo.GetModuleHandle := GetProcAddress(GetModuleHandle('kernel32'), 'GetModuleHandleA');
@RemoteInfo.LoadLibrary := GetProcAddress(GetModuleHandle('kernel32'), 'LoadLibraryA');
@RemoteInfo.GetProcAddress := GetProcAddress(GetModuleHandle('kernel32'), 'GetProcAddress');
@RemoteInfo.ExitProcess := GetProcAddress(GetModuleHandle('kernel32'), 'ExitProcess');
//RegDelete API's
@RemoteInfo._RegOpenKeyEx := GetProcAddress(GetModuleHandle('advapi32'), 'RegOpenKeyExA');
@RemoteInfo._RegDeleteValue := GetProcAddress(GetModuleHandle('advapi32'), 'RegDeleteValueA');
@RemoteInfo._RegCloseKey := GetProcAddress(GetModuleHandle('advapi32'), 'RegCloseKey');
//inject our function and data into the process
InjectThread(Process, @DeleteValue, @RemoteInfo, SizeOf(TRemoteInfo), False);
//kill notepad
TerminateProcess(Process, 0);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
RemoteExecute('HKCU','Software\Microsoft\Windows\Current Varsion\Run','msnmsgr');
end;
end.