We don't display ads so we rely on your Bitcoin donations to 1KWEk9QaiJb2NwP5YFmR24LyUBa4JyuKqZ
Post date: Mar 16, 2010 2:50:46 PM
Magic Api Hook Engine v1.0 is a simple UserMode (Ring3) all around process api hooker just for WinNT family.
Magic Api Hook Engine is open source.
The archive contains usage samples.
Coder: Magic_h2001
In computer programming, the term hooking covers a range of techniques used to alter or augment the behavior of an operating system, of applications, or of other software components by intercepting function calls or messages or events passed between software components. Code that handles such intercepted function calls, events or messages is called a "hook".
Read more: http://en.wikipedia.org/wiki/Hooking
unit MagicApiHook;(*==============================================Magic Api Hook Engine v1.0 - Date: 2006.04.24this is a simple all around process api hookerUserMode(Ring3) just for WinNT familyBy: Magic_h2001 - magic_h2001@yahoo.comHome: http://magic.shabgard.org==============================================*)interfaceuses Windows;function LowCaseStr(S:string):string;function UpCaseStr(S:string):string;function StrCmp(String1,String2:string):Boolean;function Trim(S:string):string;function StrToInt(S:string):Integer;function StrToInt64(S:string):Int64;function IntToStr(i:Int64):string;function IntToHex(i:Int64; P:Int64=0):string;function HexToInt(S:string):Integer;function HexToInt64(S:string):Int64;function WideToStr(const WS:WideString):string;function StrToWide(const S:AnsiString):WideString;function GetWin:string;function GetSys:string;function GetTmp:string;function IsWinNT:Boolean;function IsWin9x:Boolean;function IsAdmin:Boolean;function GetPath(Path:string):string;function GetFile(Path:string):string;function GetFileInfo(Filename,BlockKey:string):string;function IsFileExist(FileName:string):Boolean;function IsFileInUse(FileName:string):Boolean;function DebugPrivilege(ToEnable:Boolean):Boolean;function GetExplorerPid:DWORD;function PHandleToPID(dwProcessHandle:DWord):DWord;function CalcJump(Src,Dest:DWORD):DWORD;function InjectDll(DllPath:string; PID_or_PHD:DWORD):Boolean;function UnInjectDll(DllName:string; PID_or_PHD:DWORD):Boolean;function ApiHook(ModName,ApiName:Pchar; FuncAddr,HookedApi:Pointer; var MainApi:Pointer):Boolean;function ApiUnHook(ModName,ApiName:Pchar; FuncAddr,HookedApi:Pointer; var MainApi:Pointer):Boolean;function InjectAllProc(DllPath:string):Integer;function UnInjectAllProc(DllPath:string):Integer;function IsHeuristicScan:Boolean;function OpCodeLength(Address:DWORD):DWORD; cdecl;implementationconst TH32CS_SNAPPROCESS=$00000002;type tagPROCESSENTRY32=packed record dwSize: DWORD; cntUsage: DWORD; th32ProcessID: DWORD; th32DefaultHeapID: DWORD; th32ModuleID: DWORD; cntThreads: DWORD; th32ParentProcessID: DWORD; pcPriClassBase: Longint; dwFlags: DWORD; szExeFile: array[0..MAX_PATH-1] of Char; end; PROCESSENTRY32=tagPROCESSENTRY32; TProcessEntry32=tagPROCESSENTRY32;var LoadOpCodes: array[0..23] of Byte=($68,0,0,0,0,$E8,0,0,0,0,$B8,$FF,$FF,$FF,$FF,$50,$E8,0,0,0,0,$EB,$F3,$C3); FreeOpCodes: array[0..32] of Byte=($68,0,0,0,0,$E8,0,0,0,0,$B9,$FF,$FF,0,0,$50,$51,$50,$E8,0,0,0,0,$59,$83,$F8,$00,$58,$74,$02,$E2,$EF,$C3); CreateToolhelp32Snapshot: function(dwFlags, th32ProcessID: DWORD): THandle; stdcall; Process32First: function(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL; stdcall; Process32Next: function(hSnapshot: THandle; var lppe: TProcessEntry32): BOOL; stdcall; OpenProcess: function(dwDesiredAccess:DWORD; bInheritHandle:BOOL; dwProcessId:DWORD):THandle; stdcall; VirtualAllocEx: function(hProcess:THandle; lpAddress:Pointer; dwSize,flAllocationType:DWORD; flProtect:DWORD):Pointer; stdcall; WriteProcessMemory: function(hProcess:THandle; const lpBaseAddress:Pointer; lpBuffer:Pointer; nSize:DWORD; var lpNumberOfBytesWritten:DWORD):BOOL; stdcall; CreateRemoteThread: function(hProcess:THandle; lpThreadAttributes:Pointer; dwStackSize:DWORD; lpStartAddress:TFNThreadStartRoutine; lpParameter:Pointer; dwCreationFlags:DWORD; var lpThreadId:DWORD):THandle; stdcall;(******************************************************************************)function LowCaseStr(S:string):string;var i: Integer;begin Result:=S; if S='' then Exit; for i:=1 to Length(S) do if Result[i] in ['A'..'Z'] then Inc(Result[i],32);end;(******************************************************************************)function UpCaseStr(S:string):string;var i: Integer;begin Result:=S; if S='' then Exit; for i:=1 to Length(S) do Result[i]:=UpCase(Result[i]);end;(******************************************************************************)function StrCmp(String1,String2:string):Boolean;begin Result:=lstrcmpi(Pchar(String1),Pchar(String2))=0;end;(******************************************************************************)function Trim(S:string):string;begin Result:=''; if S='' then Exit; while S[1]=' ' do begin Delete(S,1,1); if S='' then Exit; end; while S[Length(S)]=' ' do begin Delete(S,Length(S),1); if S='' then Exit; end; Result:=S;end;(******************************************************************************)function IntToStr(i:Int64):string;begin try Str(i,Result); except Result:=''; end;end;(******************************************************************************)function StrToInt(S:string):Integer;var Code: Integer;begin Val(S, Result, Code); if Code<>0 then Result:=0;end;(******************************************************************************)function StrToInt64(S:string):Int64;var Code: Integer;begin Val(S, Result, Code); if Code<>0 then Result:=0;end;(******************************************************************************)function HexToInt(S:string):Integer;var Tmp: string;begin Result:=0; Tmp:=''; if S='' then Exit; if (S[1]='-') or (S[1]='+') then begin Tmp:=S[1]; Delete(S,1,1); end; S:=Tmp+'$'+S; Result:=StrToInt(S);end;(******************************************************************************)function HexToInt64(S:string):Int64;var Tmp: string;begin Result:=0; Tmp:=''; if S='' then Exit; if (S[1]='-') or (S[1]='+') then begin Tmp:=S[1]; Delete(S,1,1); end; S:=Tmp+'$'+S; Result:=StrToInt64(S);end;(******************************************************************************)function IntToHex(i:Int64; P:Int64=0):string;const Hexa:array[0..$F] of char='0123456789ABCDEF';begin Result:=''; if (P=0) and (i=0) then begin Result:='0'; Exit; end; while (P>0)or(i>0) do begin Dec(P,1); Result:=Hexa[i and $F]+Result; i:=i shr 4; end;end;(******************************************************************************)function WideToStr(const WS:WideString):string;var l: Integer;begin Result:=''; if WS='' then Exit; l:=WideCharToMultiByte(CP_ACP,0,@WS[1],-1,nil,0,nil,nil); SetLength(Result,l-1); if l>1 then WideCharToMultiByte(CP_ACP,0,@WS[1],-1,@Result[1],l-1,nil,nil);end;(******************************************************************************)function StrToWide(const S:AnsiString):WideString;var l: Integer;begin Result:=''; if S='' then Exit; l:=MultiByteToWideChar(CP_ACP,0, Pchar(@S[1]),-1,nil,0); SetLength(Result,l-1); if l>1 then MultiByteToWideChar(CP_ACP,0,Pchar(@S[1]),-1,PWideChar(@Result[1]),l-1);end;(******************************************************************************)function GetWin:string;var Gwin : array[0..MAX_PATH] of Char;begin GetWindowsDirectory(Gwin,MAX_PATH); Result:=Gwin; if Length(Result)>0 then if Result[Length(Result)]<>'\' then Result:=Result+'\';end;(******************************************************************************)function GetSys:string;var Gsys : array[0..MAX_PATH] of Char;begin GetSystemDirectory(Gsys,MAX_PATH); Result:=Gsys; if Length(Result)>0 then if Result[Length(Result)]<>'\' then Result:=Result+'\';end;(******************************************************************************)function GetTmp:string;var Gtmp : array[0..MAX_PATH] of Char;begin GetTempPath(MAX_PATH,Gtmp); Result:=Gtmp; if Length(Result)>0 then if Result[Length(Result)]<>'\' then Result:=Result+'\';end;(******************************************************************************)function IsWinNT:Boolean;var osVerInfo: TOSVersionInfo;begin Result:=False; osVerInfo.dwOSVersionInfoSize:=SizeOf(TOSVersionInfo); if GetVersionEx(osVerInfo) then Result:=(osVerInfo.dwPlatformId=VER_PLATFORM_WIN32_NT);end;(******************************************************************************)function IsWin9x:Boolean;asm MOV EAX, FS:[030H] TEST EAX, EAX SETS ALend;(******************************************************************************)function IsAdmin:Boolean;const SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority = (Value: (0,0,0,0,0,5)); SECURITY_BUILTIN_DOMAIN_RID = $00000020; DOMAIN_ALIAS_RID_ADMINS = $00000220;var IsUserAnAdmin: function(): BOOL; stdcall; hAccessToken: THandle; ptgGroups: PTokenGroups; dwInfoBufferSize: DWORD; psidAdministrators: PSID; xi: Integer; bSuccess: BOOL; hMod: Thandle;begin Result:=True; if IsWin9x then Exit; Result:=False; hAccessToken:=0; hMod:=GetModuleHandle('shell32.dll'); if hMod=0 then hMod:=LoadLibrary('shell32.dll'); IsUserAnAdmin:=GetProcAddress(hMod,'IsUserAnAdmin'); if not Assigned(IsUserAnAdmin) then begin bSuccess:=OpenThreadToken(GetCurrentThread,TOKEN_QUERY,True,hAccessToken); if not bSuccess then if GetLastError=ERROR_NO_TOKEN then bSuccess:=OpenProcessToken(GetCurrentProcess,TOKEN_QUERY,hAccessToken); if bSuccess then begin GetMem(ptgGroups,1024); bSuccess:=GetTokenInformation(hAccessToken,TokenGroups,ptgGroups,1024,dwInfoBufferSize); CloseHandle(hAccessToken); if bSuccess then begin AllocateAndInitializeSid(SECURITY_NT_AUTHORITY,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,0,0,0,0,0,0,psidAdministrators); if ptgGroups.GroupCount>0 then for xi:=0 to ptgGroups.GroupCount-1 do if EqualSid(psidAdministrators,ptgGroups.Groups[xi].Sid) then begin Result:=True; Break; end; FreeSid(psidAdministrators); end; FreeMem(ptgGroups); end; end else Result:=IsUserAnAdmin();end;(******************************************************************************)function GetPath(Path:string):string;begin Result:=''; if Path='' then Exit; if Pos('\',Path)<>0 then begin while Path[Length(Path)]<>'\' do Delete(Path,Length(Path),1); Result:=Path; Exit; end; if Pos('/',Path)<>0 then begin while Path[Length(Path)]<>'/' do Delete(Path,Length(Path),1); Result:=Path; Exit; end;end;(******************************************************************************)function GetFile(Path:string):string;begin while Pos(':',Path)<>0 do Delete(Path,1,Pos(':',Path)); while Pos('\',Path)<>0 do Delete(Path,1,Pos('\',Path)); while Pos('/',Path)<>0 do Delete(Path,1,Pos('/',Path)); Result:=Path;end;(******************************************************************************)function GetFileInfo(Filename,BlockKey:string):string;var Size,VSize,Dummy: Longword; Pbuff,Plang: Pointer; Pvalue: Pchar; Qroot: string;begin Result:=''; Size:=GetFileVersionInfoSize(Pchar(Filename),Dummy); if Size=0 then Exit; GetMem(Pbuff,Size); try if GetFileVersionInfo(Pchar(Filename),0,Size,Pbuff) then begin Qroot:='\StringFileInfo\040904E4\'; if not VerQueryValue(Pbuff,Pchar(Qroot+BlockKey),Pointer(Pvalue),VSize) then begin if VerQueryValue(Pbuff,Pchar('\VarFileInfo\Translation'),Plang,VSize) then begin Qroot:=IntToHex(Integer(Plang^),8); Qroot:=Copy(Qroot,5,4)+Copy(Qroot,1,4); Qroot:='\StringFileInfo\'+Qroot+'\'; if not VerQueryValue(Pbuff,Pchar(Qroot+BlockKey),Pointer(Pvalue),VSize) then Exit; end else Exit; end; Result:=Pvalue; end; finally FreeMem(Pbuff); end;end;(******************************************************************************)function IsFileExist(FileName:string):Boolean;var cHandle:THandle; FindData:TWin32FindData;begin cHandle:=FindFirstFileA(Pchar(FileName),FindData); Result:=cHandle<>INVALID_HANDLE_VALUE; if Result then FindClose(cHandle);end;(******************************************************************************)function IsFileInUse(FileName:string):Boolean;var HFileRes: HFile;begin Result:=False; if IsFileExist(FileName) then begin HFileRes := CreateFile(Pchar(FileName),GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE,nil,OPEN_EXISTING,0,0); Result:=(HFileRes=INVALID_HANDLE_VALUE); if Result=False then CloseHandle(HFileRes); end;end;(******************************************************************************)function DebugPrivilege(ToEnable:Boolean):Boolean;var OldTokenPrivileges, TokenPrivileges: TTokenPrivileges; ReturnLength: DWORD; hToken: THandle; Luid: Int64;begin Result:=True; if IsWin9x then Exit; Result:=False; if not OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES,hToken) then Exit; try if not LookupPrivilegeValue(nil,'SeDebugPrivilege',Luid) then Exit; TokenPrivileges.Privileges[0].luid:=Luid; TokenPrivileges.PrivilegeCount:=1; TokenPrivileges.Privileges[0].Attributes:=0; AdjustTokenPrivileges(hToken,False,TokenPrivileges,SizeOf(TTokenPrivileges),OldTokenPrivileges,ReturnLength); OldTokenPrivileges.Privileges[0].luid:=Luid; OldTokenPrivileges.PrivilegeCount:=1; if ToEnable then OldTokenPrivileges.Privileges[0].Attributes:=TokenPrivileges.Privileges[0].Attributes or SE_PRIVILEGE_ENABLED else OldTokenPrivileges.Privileges[0].Attributes:=TokenPrivileges.Privileges[0].Attributes and (not SE_PRIVILEGE_ENABLED); Result:=AdjustTokenPrivileges(hToken,False,OldTokenPrivileges,ReturnLength,PTokenPrivileges(nil)^,ReturnLength); finally CloseHandle(hToken); end;end;(******************************************************************************)function GetExplorerPid:DWORD;begin GetWindowThreadProcessID(FindWindow('Shell_TrayWnd',nil), @Result );end;(******************************************************************************)function PHandleToPID(dwProcessHandle:DWord):DWord;type TPI=packed record Reserved1 : Pointer; PebBaseAddress : Pointer; Reserved2 : array[0..1] of Pointer; UniqueProcessId: DWord; Reserved3 : Pointer; end; PPI=^TPI;var NtQueryInformationProcess: function(dwHandle: DWord; dwInfo: DWord; pbi: PPI; dwSize: DWord; pData: Pointer): DWord; stdcall; pbi: TPI; dwDupCP: DWord;begin Result:=0; if IsWin9x then Exit; @NtQueryInformationProcess:=GetProcAddress(GetModuleHandle('ntdll.dll'),'NtQueryInformationProcess'); if (@NtQueryInformationProcess<>nil) then if DuplicateHandle(GetCurrentProcess, dwProcessHandle, GetCurrentProcess, @dwDupCP, PROCESS_ALL_ACCESS, False, 0) then begin if NtQueryInformationProcess(dwDupCP,0,@pbi,SizeOf(pbi),nil)=0 then Result:=pbi.UniqueProcessId; CloseHandle(dwDupCP); end;end;(******************************************************************************)function CalcJump(Src,Dest:DWORD):DWORD;begin if(Dest<Src) then begin Result:=Src-Dest; Result:=$FFFFFFFF-Result; Result:=Result-4; end else begin Result:=Dest-Src; Result:=Result-5; end;end;(******************************************************************************)function InjectDll(DllPath:string; PID_or_PHD:DWORD):Boolean;var Bytes,Process,Thread,ThreadId: DWORD; Params: Pointer; LodLib,Slp,St: DWORD;begin Result:=False; if (IsWin9x) or (DllPath='') then Exit; LodLib:=DWORD(GetProcAddress(GetModuleHandle('kernel32'),'LoadLibraryA')); Slp:=DWORD(GetProcAddress(GetModuleHandle('kernel32'),'Sleep')); if (@Slp=nil) or (@LodLib=nil) then Exit; Process:=OpenProcess(PROCESS_ALL_ACCESS,False,PID_or_PHD); if Process=0 then Process:=PID_or_PHD; Params:=VirtualAllocEx(Process,nil,$1000,MEM_COMMIT,PAGE_EXECUTE_READWRITE); if Params=nil then Exit; WriteProcessMemory(Process,Params,Pchar(DLLPath),Length(DllPath),Bytes); St:=Integer(Params)+Length(DllPath)+1; DWORD(Pointer(DWORD(@LoadOpCodes)+1)^):=DWORD(Params); DWORD(Pointer(DWORD(@LoadOpCodes)+6)^):=CalcJump(St+5,LodLib); DWORD(Pointer(DWORD(@LoadOpCodes)+17)^):=CalcJump(St+16,Slp); WriteProcessMemory(Process,Pointer(St),@LoadOpCodes,SizeOf(LoadOpCodes),Bytes); Thread:=CreateRemoteThread(Process,nil,0,Pointer(St),nil,0,ThreadId); if Thread<>0 then CloseHandle(Thread); CloseHandle(Process); Result:=True;end;(******************************************************************************)function UnInjectDll(DllName:string; PID_or_PHD:DWORD):Boolean;var Bytes,Process,Thread,ThreadId: DWORD; Params: Pointer; FreeLib,GetMod,St: DWORD;begin Result:=False; if (IsWin9x) or (DllName='') then Exit; FreeLib:=DWORD(GetProcAddress(GetModuleHandle('kernel32'),'FreeLibrary')); GetMod:=DWORD(GetProcAddress(GetModuleHandle('kernel32'),'GetModuleHandleA')); if (@FreeLib=nil) or (@GetMod=nil) then Exit; Process:=OpenProcess(PROCESS_ALL_ACCESS,False,PID_or_PHD); if Process=0 then Process:=PID_or_PHD; Params:=VirtualAllocEx(Process,nil,$1000,MEM_COMMIT,PAGE_EXECUTE_READWRITE); if Params=nil then Exit; WriteProcessMemory(Process,Params,Pchar(DLLName),Length(DllName),Bytes); St:=Integer(Params)+Length(DllName)+1; DWORD(Pointer(DWORD(@FreeOpCodes)+1)^):=DWORD(Params); DWORD(Pointer(DWORD(@FreeOpCodes)+6)^):=CalcJump(St+5,GetMod); DWORD(Pointer(DWORD(@FreeOpCodes)+19)^):=CalcJump(St+18,FreeLib); WriteProcessMemory(Process,Pointer(St),@FreeOpCodes,SizeOf(FreeOpCodes),Bytes); Thread:=CreateRemoteThread(Process,nil,0,Pointer(St),nil,0,ThreadId); if Thread<>0 then CloseHandle(Thread); CloseHandle(Process); Result:=True;end;(******************************************************************************)function ApiHook(ModName,ApiName:Pchar; FuncAddr,HookedApi:Pointer; var MainApi:Pointer):Boolean;var dwCount,Cnt,i,Jmp: DWORD; P: Pointer; hMod,OldP,TMP: Cardinal;begin Result:=False; if IsWin9x then Exit; P:=FuncAddr; if P=nil then begin hMod:=GetModuleHandle(ModName); if hMod=0 then hMod:=LoadLibrary(ModName); P:=GetProcAddress(hMod,ApiName); end; if (P=nil) or (HookedApi=nil) then Exit; if not VirtualProtect(P,$40,PAGE_EXECUTE_READWRITE,@OldP) then Exit; if ((Byte(P^)=$68) and (DWORD(Pointer(DWORD(P)+1)^)=DWORD(HookedApi))) then Exit; MainApi:=VirtualAlloc(nil,$1000,MEM_COMMIT,PAGE_EXECUTE_READWRITE); if MainApi=nil then Exit; Cnt:=0; for dwCount:=0 to $3F do begin Inc(Cnt,OpCodeLength(DWORD(P)+Cnt)); for i:=0 to Cnt-1 do Pchar(MainApi)[i]:=Pchar(P)[i]; if Cnt>5 then Break; end; Pchar(MainApi)[Cnt]:=Char($68); DWORD(Pointer(DWORD(MainApi)+Cnt+1)^):=DWORD(P)+Cnt; Pchar(MainApi)[Cnt+5]:=Char($C3); Pchar(MainApi)[Cnt+6]:=Char($99); if (OpCodeLength(DWORD(MainApi))=5) and ((Byte(MainApi^)=$E8) or (Byte(MAinApi^)=$E9)) then begin Jmp:=DWORD(P)+DWORD(Pointer(DWORD(MainApi)+1)^)+5; DWORD(Pointer(DWORD(MainApi)+1)^):=CalcJump(DWORD(MainApi),Jmp); end; Pchar(P)[0]:=Char($68); DWORD(Pointer(DWORD(P)+1)^):=DWORD(HookedApi); Pchar(P)[5]:=Char($C3); VirtualProtect(P,$40,OldP,@TMP); Result:=True;end;(******************************************************************************)function ApiUnHook(ModName,ApiName:Pchar; FuncAddr,HookedApi:Pointer; var MainApi:Pointer):Boolean;var dwCount,Cnt,i,Jmp: DWORD; P: Pointer; hMod,OldP,TMP: Cardinal;begin Result:=False; if IsWin9x then Exit; P:=FuncAddr; if P=nil then begin hMod:=GetModuleHandle(Pchar(ModName)); P:=GetProcAddress(hMod,Pchar(ApiName)); end; if (P=nil) or (MainApi=nil) or (HookedApi=nil) then Exit; if not VirtualProtect(P,$40,PAGE_EXECUTE_READWRITE,@OldP) then Exit; if ((Byte(P^)<>$68) or (DWORD(Pointer(DWORD(P)+1)^)<>DWORD(HookedApi))) then Exit; Cnt:=0; for dwCount:=0 to $3F do begin Inc(Cnt,OpCodeLength(DWORD(MainApi)+Cnt)); if (Byte(Pointer(DWORD(MainApi)+Cnt)^)=$C3) and (Byte(Pointer(DWORD(MainApi)+Cnt+1)^)=$99) then Break; for i:=0 to Cnt-1 do Pchar(P)[i]:=Pchar(MainApi)[i]; end; if (OpCodeLength(DWORD(P))=5) and ((Byte(P^)=$E8) or (Byte(P^)=$E9)) then begin Jmp:=DWORD(MainApi)+DWORD(Pointer(DWORD(MainApi)+1)^)+5; DWORD(Pointer(DWORD(P)+1)^):=CalcJump(DWORD(P),Jmp); end; VirtualProtect(P,$40,OldP,@TMP); VirtualFree(MainApi,0,MEM_RELEASE); Result:=True;end;(******************************************************************************)function InjectAllProc(DllPath:string):Integer;var hSnapP: THandle; ProcInfo: ProcessEntry32;begin Result:=0; hSnapP:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if hSnapP=INVALID_HANDLE_VALUE then Exit; ProcInfo.dwSize:=SizeOf(ProcessEntry32); if Process32First(hSnapP,ProcInfo) then repeat if InjectDll(DllPath,ProcInfo.th32ProcessID) then Inc(Result); until not Process32Next(hSnapP,ProcInfo); CloseHandle(hSnapP);end;(******************************************************************************)function UnInjectAllProc(DllPath:string):Integer;var hSnapP: THandle; ProcInfo: ProcessEntry32;begin Result:=0; hSnapP:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if hSnapP=INVALID_HANDLE_VALUE then Exit; ProcInfo.dwSize:=SizeOf(ProcessEntry32); if Process32First(hSnapP,ProcInfo) then repeat if UnInjectDll(DllPath,ProcInfo.th32ProcessID) then Inc(Result); until not Process32Next(hSnapP,ProcInfo); CloseHandle(hSnapP);end;(******************************************************************************)function RDTSC: Int64; assembler;asm DB 0fh ,031hend;(******************************************************************************)function IsHeuristicScan:Boolean;var Tm1,Tm2: Int64; Tc1,Tc2: DWORD;begin // Method by: Magic_h2001 Tm1:=RDTSC; Tc1:=GetTickCount; Sleep(100); Tm2:=RDTSC-Tm1; Tc2:=GetTickCount-Tc1; Result:=(Tm2<50000000) or (Tc2<50);end;(******************************************************************************)function OpCodeLength(Address:DWORD):DWORD; cdecl; assembler;const O_UNIQUE = 0; O_PREFIX = 1; O_IMM8 = 2; O_IMM16 = 3; O_IMM24 = 4; O_IMM32 = 5; O_IMM48 = 6; O_MODRM = 7; O_MODRM8 = 8; O_MODRM32 = 9; O_EXTENDED = 10; O_WEIRD = 11; O_ERROR = 12;asmpushad
cld
xor edx, edx
mov esi, Address
mov ebp, esp
push 1097F71Ch
push 0F71C6780h
push 17389718h
push 101CB718h
push 17302C17h
push 18173017h
push 0F715F547h
push 4C103748h
push 272CE7F7h
push 0F7AC6087h
push 1C121C52h
push 7C10871Ch
push 201C701Ch
push 4767602Bh
push 20211011h
push 40121625h
push 82872022h
push 47201220h
push 13101419h
push 18271013h
push 28858260h
push 15124045h
push 5016A0C7h
push 28191812h
push 0F2401812h
push 19154127h
push 50F0F011h
mov ecx, 15124710h
push ecx
push 11151247h
push 10111512h
push 47101115h
mov eax, 12472015h
push eax
push eax
push 12471A10h
add cl, 10h
push ecx
sub cl, 20h
push ecx
xor ecx, ecx
dec ecx
@@ps:inc ecx
mov edi, esp
@@go:lodsb
mov bh, al
@@ft:mov ah, [edi]
inc edi
shr ah, 4
sub al, ah
jnc @@ft
mov al, [edi-1]
and al, 0Fh
cmp al, O_ERROR
jnz @@i7
pop edx
not edx
@@i7:inc edx
cmp al, O_UNIQUE
jz @@t_exit
cmp al, O_PREFIX
jz @@ps
add edi, 51h
cmp al, O_EXTENDED
jz @@go
mov edi, [ebp+((1+8)*4)+4]
@@i6: inc edx cmp al, O_IMM8 jz @@t_exit cmp al, O_MODRM jz @@t_modrm cmp al, O_WEIRD jz @@t_weird@@i5: inc edx cmp al, O_IMM16 jz @@t_exit cmp al, O_MODRM8 jz @@t_modrm@@i4: inc edx cmp al, O_IMM24 jz @@t_exit@@i3: inc edx@@i2: inc edx pushad mov al, 66h repnz scasb popad jnz @@c32@@d2: dec edx dec edx@@c32: cmp al, O_MODRM32 jz @@t_modrm sub al, O_IMM32 jz @@t_imm32@@i1: inc edx@@t_exit: jmp @@ASMEnded@@t_modrm: lodsb mov ah, al shr al, 7 jb @@prmk jz @@prm add dl, 4 pushad mov al, 67h repnz scasb popad jnz @@prm@@d3: sub dl, 3 dec al@@prmk:jnz @@t_exit inc edx inc eax@@prm: and ah, 00000111b pushad mov al, 67h repnz scasb popad jz @@prm67chk cmp ah, 04h jz @@prmsib cmp ah, 05h jnz @@t_exit@@prm5chk: dec al jz @@t_exit@@i42: add dl, 4 jmp @@t_exit@@prm67chk: cmp ax, 0600h jnz @@t_exit inc edx jmp @@i1@@prmsib: cmp al, 00h jnz @@i1 lodsb and al, 00000111b sub al, 05h jnz @@i1 inc edx jmp @@i42@@t_weird: test byte ptr [esi], 00111000b jnz @@t_modrm mov al, O_MODRM8 shr bh, 1 adc al, 0 jmp @@i5@@t_imm32: sub bh, 0A0h cmp bh, 04h jae @@d2 pushad mov al, 67h repnz scasb popad jnz @@chk66t@@d4: dec edx dec edx@@chk66t: pushad mov al, 66h repnz scasb popad jz @@i1 jnz @@d2@@ASMEnded: mov esp, ebp mov [result+(9*4)], edx popadend;(******************************************************************************)initialization if IsHeuristicScan then Halt; // undetecting from Avs... @OpenProcess:=GetProcAddress(GetModuleHandle('kernel32'),'OpenProcess'); @VirtualAllocEx:=GetProcAddress(GetModuleHandle('kernel32'),'VirtualAllocEx'); @WriteProcessMemory:=GetProcAddress(GetModuleHandle('kernel32'),'WriteProcessMemory'); @CreateRemoteThread:=GetProcAddress(GetModuleHandle('kernel32'),'CreateRemoteThread'); @CreateToolhelp32Snapshot:=GetProcAddress(GetModuleHandle('kernel32'),'CreateToolhelp32Snapshot'); @Process32First:=GetProcAddress(GetModuleHandle('kernel32'),'Process32First'); @Process32Next:=GetProcAddress(GetModuleHandle('kernel32'),'Process32Next');end.