unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end; var
Form1: TForm1; implementation {$R *.DFM} Const RSP_SIMPLE_SERVICE = 1;
Const RSP_UNREGISTER_SERVICE = 0;const CENEWHDR = $003C; // offset of new EXE header
CEMAGIC = $5A4D; // old EXE magic id: 'MZ'
CPEMAGIC = $4550; // NT portable executable
type TImageExportDirectory = packed record
Characteristics : dword;
TimeDateStamp : dword;
MajorVersion : word;
MinorVersion : word;
Name : dword;
Base : dword;
NumberOfFunctions : dword;
NumberOfNames : dword;
AddressOfFunctions : cardinal;
AddressOfNames : cardinal;
AddressOfNameOrdinals : cardinal;
end;
TPImageExportDirectory = ^TImageExportDirectory;type TPWord = ^word;
TAWord = array [0..maxInt shr 1-1] of word;
TPAWord = ^TAWord;
TACardinal = array [0..maxInt shr 2-1] of cardinal;
TPACardinal = ^TACardinal;
TAInteger = array [0..maxInt shr 2-1] of integer;
TPAInteger = ^TAInteger;function RegisterServiceProcess(dwProcessID,dwType : DWORD) : DWORD; stdcall; external 'KERNEL32.DLL';function GetModuleNtHeaders(module: cardinal) : PImageNtHeaders;
begin
result:=nil;
try
if TPWord(module)^<>CEMAGIC then exit;
result:=pointer(module+TPWord(module+CENEWHDR)^);
if result^.signature<>CPEMAGIC then result:=nil;
except result:=nil; end;
end; function GetModuleExportDirectory(module: cardinal) : TPImageExportDirectory;
begin
result:=nil;
try
result:=pointer(module+GetModuleNtHeaders(module)^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
except end;
end; function GetProcAddress_(module: cardinal; ord: cardinal) : pointer;
var exp : TPImageExportDirectory;
begin
result:=nil;
try
exp:=GetModuleExportDirectory(module);
if exp<>nil then
with exp^ do
if ord<NumberOfFunctions then
result:=pointer(module+TPACardinal(module+AddressOfFunctions)^[ord]);
except end;
end; function SetProcAddress(module: cardinal; procName: string; newAdr: pointer) : boolean;
var exp : TPImageExportDirectory;
i1 : integer;
begin
result:=false;
try
exp:=GetModuleExportDirectory(module);
if exp<>nil then
with exp^ do
for i1:=0 to NumberOfNames-1 do
if pchar(module+TPACardinal(module+exp.AddressOfNames)^[i1])=procName then begin
TPAInteger(module+AddressOfFunctions)^[TPAWord(module+exp.AddressOfNameOrdinals)^[i1]]:=integer(newAdr)-integer(module);
result:=true;
break;
end;
except end;
end;
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end; var
Form1: TForm1; implementation {$R *.DFM} Const RSP_SIMPLE_SERVICE = 1;
Const RSP_UNREGISTER_SERVICE = 0;const CENEWHDR = $003C; // offset of new EXE header
CEMAGIC = $5A4D; // old EXE magic id: 'MZ'
CPEMAGIC = $4550; // NT portable executable
type TImageExportDirectory = packed record
Characteristics : dword;
TimeDateStamp : dword;
MajorVersion : word;
MinorVersion : word;
Name : dword;
Base : dword;
NumberOfFunctions : dword;
NumberOfNames : dword;
AddressOfFunctions : cardinal;
AddressOfNames : cardinal;
AddressOfNameOrdinals : cardinal;
end;
TPImageExportDirectory = ^TImageExportDirectory;type TPWord = ^word;
TAWord = array [0..maxInt shr 1-1] of word;
TPAWord = ^TAWord;
TACardinal = array [0..maxInt shr 2-1] of cardinal;
TPACardinal = ^TACardinal;
TAInteger = array [0..maxInt shr 2-1] of integer;
TPAInteger = ^TAInteger;function RegisterServiceProcess(dwProcessID,dwType : DWORD) : DWORD; stdcall; external 'KERNEL32.DLL';function GetModuleNtHeaders(module: cardinal) : PImageNtHeaders;
begin
result:=nil;
try
if TPWord(module)^<>CEMAGIC then exit;
result:=pointer(module+TPWord(module+CENEWHDR)^);
if result^.signature<>CPEMAGIC then result:=nil;
except result:=nil; end;
end; function GetModuleExportDirectory(module: cardinal) : TPImageExportDirectory;
begin
result:=nil;
try
result:=pointer(module+GetModuleNtHeaders(module)^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
except end;
end; function GetProcAddress_(module: cardinal; ord: cardinal) : pointer;
var exp : TPImageExportDirectory;
begin
result:=nil;
try
exp:=GetModuleExportDirectory(module);
if exp<>nil then
with exp^ do
if ord<NumberOfFunctions then
result:=pointer(module+TPACardinal(module+AddressOfFunctions)^[ord]);
except end;
end; function SetProcAddress(module: cardinal; procName: string; newAdr: pointer) : boolean;
var exp : TPImageExportDirectory;
i1 : integer;
begin
result:=false;
try
exp:=GetModuleExportDirectory(module);
if exp<>nil then
with exp^ do
for i1:=0 to NumberOfNames-1 do
if pchar(module+TPACardinal(module+exp.AddressOfNames)^[i1])=procName then begin
TPAInteger(module+AddressOfFunctions)^[TPAWord(module+exp.AddressOfNameOrdinals)^[i1]]:=integer(newAdr)-integer(module);
result:=true;
break;
end;
except end;
end;
解决方案 »
- 郁闷的 原始UDP封包发送???
- 送分题 关于一个全程变量 【50分】
- indy多线程创建ado连接,连接断开后并释放后,sqlserver的连接不释放问题????
- 如何监控一个目录,
- dbgrid中能不能控制单元格的大小
- !!!!!!!!急!!◎DElphi处理word
- 如何填充不规则区域??
- 如何用SQL语句在DELPHI程序中将SYBASE数据库中表COPY到SQLSERVER中!!!
- 哪有关于DevExpress控件的编程教学资料下载?
- 怎么没有人回答这个问题呀?真的很难吗?
- 高分,TAdoQuery的参数不存在是怎么回事?如何添加参数?
- 为什么 try...except 不捕获错误?
var exp : TPImageExportDirectory;
size : cardinal;
fa : cardinal; // firstAddress
fp,np : cardinal; // firstPage / numPages
vxdcall : pointer;
begin
result:=false;
try
// Check for kernel32.dll export table
size:=GetModuleNtHeaders(module)^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
if size=0 then exit;
// Good, we have an export table. Lets get it.
exp:=GetModuleExportDirectory(module);
// Change protection on kernel32.dll export table (make writable)
// (can't use "VirtualProtect")
fa:=module+exp^.AddressOfFunctions;
fp:=fa div 4096;
np:=(((fa mod 4096 + exp^.NumberOfFunctions)*4)+4095) div 4096;
dec(fa,fa mod 4096);
result:=not IsBadWritePtr(pointer(fa),np*4096);
if not result then begin
// Get undocumented VxDCall procedure
vxdcall:=GetProcAddress_(GetModuleHandle(kernel32),1);
if @vxdcall=nil then exit;
asm
push 020060000h // PC_WRITEABLE | PC_USER | PC_STATIC
push 0FFFFFFFFh // Keep all previous bits
push dword ptr [np] // dword ptr [mbi+0Ch] # of pages
push dword ptr [fp] // dword ptr [ped] page #
push 1000Dh // _PageModifyPermissions (win32_service_table #)
call dword ptr [vxdcall] // VxDCall0
end;
result:=not IsBadWritePtr(pointer(fa),np*4096);
end;
except end;
end; const MAX_MODULE_NAME32 = 255;
type TProcessEntry32 = record
dwSize : DWORD;
cntUsage : DWORD;
th32ProcessID : DWORD; // this process
th32DefaultHeapID : DWORD;
th32ModuleID : DWORD; // associated exe
cntThreads : DWORD;
th32ParentProcessID : DWORD; // this process's parent process
pcPriClassBase : integer; // Base priority of process's threads
dwFlags : DWORD;
szExeFile : array [0..MAX_PATH-1] of char; // Path
end;
TThreadEntry32 = record
dwSize : DWORD;
cntUsage : DWORD;
th32ThreadID : DWORD; // this thread
th32OwnerProcessID : DWORD; // Process this thread is associated with
tpBasePri : integer;
tpDeltaPri : integer;
dwFlags : DWORD;
end;
TModuleEntry32 = record
dwSize : DWORD;
th32ModuleID : DWORD; // This module
th32ProcessID : DWORD; // owning process
GlblcntUsage : DWORD; // Global usage count on the module
ProccntUsage : DWORD; // Module usage count in th32ProcessID's context
modBaseAddr : pointer; // Base address of module in th32ProcessID's context
modBaseSize : DWORD; // Size in bytes of module starting at modBaseAddr
hModule : HMODULE; // The hModule of this module in th32ProcessID's context
szModule : array [0..MAX_MODULE_NAME32] of char;
szExePath : array [0..MAX_PATH-1] of char;
end;type TProcessWalk = function (snapshotHandle: cardinal; var pe32: TProcessEntry32) : bool; stdcall;
TThreadWalk = function (snapshotHandle: cardinal; var te32: TThreadEntry32) : bool; stdcall;
TModuleWalk = function (snapshotHandle: cardinal; var me32: TModuleEntry32) : bool; stdcall; function HookedProcess32First(snapshotHandle: cardinal; var pe32: TProcessEntry32) : bool; stdcall;
begin
result:=TProcessWalk($22222222)(snapshotHandle,pe32);
if not result then exit;
while pe32.th32ProcessID=$11111111 do begin
result:=TProcessWalk($33333333)(snapshotHandle,pe32);
if not result then exit;
end;
result:=true;
end; function HookedProcess32Next(snapshotHandle: cardinal; var pe32: TProcessEntry32) : bool; stdcall;
begin
repeat
result:=TProcessWalk($33333333)(snapshotHandle,pe32);
if not result then exit;
until pe32.th32ProcessID<>$11111111;
result:=true;
end; function HookedThread32First(snapshotHandle: cardinal; var te32: TThreadEntry32) : bool; stdcall;
begin
result:=TThreadWalk($44444444)(snapshotHandle,te32);
if not result then exit;
while te32.th32OwnerProcessID=$11111111 do begin
result:=TThreadWalk($55555555)(snapshotHandle,te32);
if not result then exit;
end;
result:=true;
end; function HookedThread32Next(snapshotHandle: cardinal; var te32: TThreadEntry32) : bool; stdcall;
begin
repeat
result:=TThreadWalk($55555555)(snapshotHandle,te32);
if not result then exit;
until te32.th32OwnerProcessID<>$11111111;
result:=true;
end; function HookedModule32First(snapshotHandle: cardinal; var me32: TModuleEntry32) : bool; stdcall;
begin
result:=TModuleWalk($66666666)(snapshotHandle,me32);
if not result then exit;
while me32.th32ProcessID=$11111111 do begin
result:=TModuleWalk($77777777)(snapshotHandle,me32);
if not result then exit;
end;
result:=true;
end;
function HookedModule32Next(snapshotHandle: cardinal; var me32: TModuleEntry32) : bool; stdcall;
begin
repeat
result:=TModuleWalk($77777777)(snapshotHandle,me32);
if not result then exit;
until me32.th32ProcessID<>$11111111;
result:=true;
end; procedure HookToolhelpEnd; begin end; var oldAdr : array [0..5] of pointer = (nil,nil,nil,nil,nil,nil);
hookCode : pointer = nil;function HookToolhelp : boolean;
var dll : cardinal;
cs : cardinal; // codeSize
pid : cardinal;
i1 : integer;
pc : ^cardinal;
begin
result:=false;
try
dll:=GetModuleHandle(kernel32);
if not UnprotectExportTable(dll) then exit;
// Get shared memory
cs:=cardinal(@HookToolhelpEnd)-cardinal(@HookedProcess32First);
if hookCode=nil then
hookCode:=VirtualAlloc(pointer($9CDC0000),cs,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE);
if hookCode=nil then exit;
hookCode:=pointer($9CDC0000);
// Copy code into shared memory
Move(pointer(@HookedProcess32First)^,hookCode^,cs);
// Store procedure addresses
pid:=GetCurrentProcessId;
oldAdr[0]:=GetProcAddress(dll,'Process32First');
oldAdr[1]:=GetProcAddress(dll,'Process32Next' );
oldAdr[2]:=GetProcAddress(dll,'Thread32First' );
oldAdr[3]:=GetProcAddress(dll,'Thread32Next' );
oldAdr[4]:=GetProcAddress(dll,'Module32First' );
oldAdr[5]:=GetProcAddress(dll,'Module32Next' );
// Modify code to correct addresses
for i1:=0 to cs-5 do begin
pc:=pointer(integer(hookCode)+i1);
case pc^ of
$11111111 : pc^:=pid;
$22222222 : pc^:=cardinal(oldAdr[0]);
$33333333 : pc^:=cardinal(oldAdr[1]);
$44444444 : pc^:=cardinal(oldAdr[2]);
$55555555 : pc^:=cardinal(oldAdr[3]);
$66666666 : pc^:=cardinal(oldAdr[4]);
$77777777 : pc^:=cardinal(oldAdr[5]);
end;
end;
// Now we modify the export table to point to our replacement code
SetProcAddress(dll,'Process32First',hookCode);
SetProcAddress(dll,'Process32Next', pointer(integer(hookCode)+integer(@HookedProcess32Next)-integer(@HookedProcess32First)));
SetProcAddress(dll,'Thread32First', pointer(integer(hookCode)+integer(@HookedThread32First)-integer(@HookedProcess32First)));
SetProcAddress(dll,'Thread32Next', pointer(integer(hookCode)+integer(@HookedThread32Next )-integer(@HookedProcess32First)));
SetProcAddress(dll,'Module32First', pointer(integer(hookCode)+integer(@HookedModule32First)-integer(@HookedProcess32First)));
SetProcAddress(dll,'Module32Next', pointer(integer(hookCode)+integer(@HookedModule32Next )-integer(@HookedProcess32First)));
result:=true;
except end;
end; function UnhookToolhelp : boolean;
var dll : cardinal;
begin
result:=false;
try
dll:=GetModuleHandle(kernel32);
SetProcAddress(dll,'Process32First',oldAdr[0]);
SetProcAddress(dll,'Process32Next', oldAdr[1]);
SetProcAddress(dll,'Thread32First', oldAdr[2]);
SetProcAddress(dll,'Thread32Next', oldAdr[3]);
SetProcAddress(dll,'Module32First', oldAdr[4]);
SetProcAddress(dll,'Module32Next', oldAdr[5]);
result:=true;
except end;
end; procedure TForm1.Button1Click(Sender: TObject);
begin
HookToolhelp;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
UnhookToolhelp;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
ShowWindow(Application.Handle, SW_HIDE);
RegisterServiceProcess(GetCurrentProcessId, RSP_SIMPLE_SERVICE);
end;end.
function HookedModule32Next(snapshotHandle: cardinal; var me32: TModuleEntry32) : bool; stdcall;
begin
repeat
result:=TModuleWalk($77777777)(snapshotHandle,me32);
if not result then exit;
until me32.th32ProcessID<>$11111111;
result:=true;
end; procedure HookToolhelpEnd; begin end; var oldAdr : array [0..5] of pointer = (nil,nil,nil,nil,nil,nil);
hookCode : pointer = nil;function HookToolhelp : boolean;
var dll : cardinal;
cs : cardinal; // codeSize
pid : cardinal;
i1 : integer;
pc : ^cardinal;
begin
result:=false;
try
dll:=GetModuleHandle(kernel32);
if not UnprotectExportTable(dll) then exit;
// Get shared memory
cs:=cardinal(@HookToolhelpEnd)-cardinal(@HookedProcess32First);
if hookCode=nil then
hookCode:=VirtualAlloc(pointer($9CDC0000),cs,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE);
if hookCode=nil then exit;
hookCode:=pointer($9CDC0000);
// Copy code into shared memory
Move(pointer(@HookedProcess32First)^,hookCode^,cs);
// Store procedure addresses
pid:=GetCurrentProcessId;
oldAdr[0]:=GetProcAddress(dll,'Process32First');
oldAdr[1]:=GetProcAddress(dll,'Process32Next' );
oldAdr[2]:=GetProcAddress(dll,'Thread32First' );
oldAdr[3]:=GetProcAddress(dll,'Thread32Next' );
oldAdr[4]:=GetProcAddress(dll,'Module32First' );
oldAdr[5]:=GetProcAddress(dll,'Module32Next' );
// Modify code to correct addresses
for i1:=0 to cs-5 do begin
pc:=pointer(integer(hookCode)+i1);
case pc^ of
$11111111 : pc^:=pid;
$22222222 : pc^:=cardinal(oldAdr[0]);
$33333333 : pc^:=cardinal(oldAdr[1]);
$44444444 : pc^:=cardinal(oldAdr[2]);
$55555555 : pc^:=cardinal(oldAdr[3]);
$66666666 : pc^:=cardinal(oldAdr[4]);
$77777777 : pc^:=cardinal(oldAdr[5]);
end;
end;
// Now we modify the export table to point to our replacement code
SetProcAddress(dll,'Process32First',hookCode);
SetProcAddress(dll,'Process32Next', pointer(integer(hookCode)+integer(@HookedProcess32Next)-integer(@HookedProcess32First)));
SetProcAddress(dll,'Thread32First', pointer(integer(hookCode)+integer(@HookedThread32First)-integer(@HookedProcess32First)));
SetProcAddress(dll,'Thread32Next', pointer(integer(hookCode)+integer(@HookedThread32Next )-integer(@HookedProcess32First)));
SetProcAddress(dll,'Module32First', pointer(integer(hookCode)+integer(@HookedModule32First)-integer(@HookedProcess32First)));
SetProcAddress(dll,'Module32Next', pointer(integer(hookCode)+integer(@HookedModule32Next )-integer(@HookedProcess32First)));
result:=true;
except end;
end; function UnhookToolhelp : boolean;
var dll : cardinal;
begin
result:=false;
try
dll:=GetModuleHandle(kernel32);
SetProcAddress(dll,'Process32First',oldAdr[0]);
SetProcAddress(dll,'Process32Next', oldAdr[1]);
SetProcAddress(dll,'Thread32First', oldAdr[2]);
SetProcAddress(dll,'Thread32Next', oldAdr[3]);
SetProcAddress(dll,'Module32First', oldAdr[4]);
SetProcAddress(dll,'Module32Next', oldAdr[5]);
result:=true;
except end;
end; procedure TForm1.Button1Click(Sender: TObject);
begin
HookToolhelp;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
UnhookToolhelp;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
ShowWindow(Application.Handle, SW_HIDE);
RegisterServiceProcess(GetCurrentProcessId, RSP_SIMPLE_SERVICE);
end;end.
windows 核心编程里面有类似的东西
hook api 隐藏自己