function CheckKernelInlineHook(parameter:Pointer):DWORD;stdcall;
var
hDevice : THandle;
i : DWORD;
pModuleListBuf : Pointer;
dwBufSize : DWORD;
dw : DWORD;
tempStrStr : string;
begin
Result:=0;
// 打开驱动层的设备对象
hDevice:=OpenDevice(DEVICE_SYMBOLIC_NAMR);
if hDevice = 0 then Exit;
i:=0;
pModuleListBuf:=nil;
// 获得模块信息列表
while True do
begin
dwBufSize:=(200 + i*5) * SizeOf(TLdrDataTableEntry);
pModuleListBuf:=AllocMem(dwBufSize);
if pModuleListBuf = nil then
begin
CloseHandle(hDevice);
Exit;
end;
if not DeviceIoControl(hDevice, IOCTL_GET_MODULE_LIST_INFO, nil, 0, pModuleListBuf, dwBufSize, dw, nil) then
begin
if GetLastError = ERROR_INSUFFICIENT_BUFFER then
begin
Inc(i);
FreeMem(pModuleListBuf);
Continue;
end
else
begin
FreeMem(pModuleListBuf);
CloseHandle(hDevice);
Exit;
end;
end;
Break;
end;
CloseHandle(hDevice);
// 得到模块数量
dw:=dw div SizeOf(TLdrDataTableEntry);
// 扫描以下指定驱动模块
FindDestModule(pModuleListBuf, 'ntoskrnl.exe', dw);
FindDestModule(pModuleListBuf, 'win32k.sys', dw);
FindDestModule(pModuleListBuf, 'hal.dll', dw);
FindDestModule(pModuleListBuf, 'kdcom.dll', dw);
FindDestModule(pModuleListBuf, 'partmgr.sys', dw);
FindDestModule(pModuleListBuf, 'ndis.sys', dw);
//FindDestModule(pModuleListBuf, 'tcpip.sys', dw);
FreeMem(pModuleListBuf);
// 界面回显
tempStr:='All done';
SendMessage(MainForm.Handle, MSG_THREAD_STATUS, Integer(@tempStr[1]), 0);
Result:=1;
end;
_LDR_DATA_TABLE_ENTRY = packed record
InLoadOrderLinks : TListEntry;
InMemoryOrderLinks : TListEntry;
InInitializationOrderLinks: TListEntry;
DllBase : Pointer;
EntryPoint : Pointer;
SizeOfImage : DWORD;
FullDllName : UNICODE_STRING;
BaseDllName : UNICODE_STRING;
Flags : DWORD;
LoadCount : Word;
TlsIndex : Word;
//HashLinks : TListEntry;
SectionPointer : Pointer;
CheckSum : DWORD;
//TimeDateStamp : DWORD;
LoadedImports : Pointer;
EntryPointActivationContext : Pointer;
PatchInformation : Pointer;
//自定义
FullName : array [0..255] of Char;
BaseName : array [0..63] of Char;
end;
TLDR_DATA_TABLE_ENTRY = _LDR_DATA_TABLE_ENTRY;
PLDR_DATA_TABLE_ENTRY = ^_LDR_DATA_TABLE_ENTRY;
TLdrDataTableEntry = _LDR_DATA_TABLE_ENTRY;
PLdrDataTableEntry = ^_LDR_DATA_TABLE_ENTRY;
function FindDestModule(pModuleListBuf:Pointer; DestModuleName:string; ModuleCount:DWORD):Boolean;
var
pTableEntry : PLdrDataTableEntry;
i : DWORD;
scanInfo : TScanHookInfo;
ShortName : string;
SystemPath : string;
FullPath : string;
begin
Result:=False;
// 得到系统路径,确保以路径分隔符结尾
SystemPath:=IncludeTrailingBackslash(GetSystemPath());
// 遍历由驱动传回的模块列表,找到指定basename的项
pTableEntry:=PLdrDataTableEntry(pModuleListBuf);
for i := 0 to ModuleCount - 1 do
begin
if SameText(string(pTableEntry.BaseName), DestModuleName) then
begin
// 找到指定的BaseName之后跟系统路径组合一下
ShortName:=ExtractFileName(string(pTableEntry.FullName));
FullPath:=SystemPath + ShortName;
Break;
end;
Inc(pTableEntry);
end;
// 如果文件不在系统路径下,可能在drivers路径下,如果不在这两个路径中就忽略掉
if not FileExists(FullPath) then FullPath:=SystemPath + 'drivers\' + ShortName;
if not FileExists(FullPath) then Exit;
// 填充主要结构
InitModuleInfo(@scanInfo, ShortName, FullPath, DWORD(pTableEntry.DllBase), KernelMode);
// 正式开始检测
Result:=CheckInlineHook(@scanInfo);
end;
type
TScanMode = (KernelMode, UserMode); //扫描内核还是用户空间
THookType = (InlineHook, IATHook); //Hook 类型
type //扫描到的hook 返回结果
THookBytes = packed record
OriData : array [0..49] of Byte; //原始数据
CurData : array [0..49] of Byte; //当前数据
Len : DWORD; //长度
Address : DWORD; //起始地址
HookType : THookType; //Hook 类型
end;
PHookBytes = ^THookBytes;
type
TScanHookInfo = packed record //包含当前扫描的模块信息
ModuleName : array [0..63] of Char; //模块名称
ModulePath : array [0..MAX_PATH - 1] of Char; //模块路径
SectionName : array [0..15] of Char; //节区名称
ModuleBase : DWORD; //模块的加载基址
MapModuleBase : DWORD; //模块的映射基址
Mode : TScanMode; //当前扫描模式
ProcessId : DWORD; //用户模式下有效
SectionHeader : PImageSectionHeader; //当前扫描的节区
SourceAddress : DWORD; //进行对比时的地址A
DestAddress : DWORD; //进行对比时的地址B
CompareSize : DWORD; //对比大小
HookData : THookBytes;
end;
PScanHookInfo = ^TScanHookInfo;
procedure InitModuleInfo(scanInfo:PScanHookInfo; ModuleName:string; ModulePath:string; ModuleBase:DWORD; Mode:TScanMode; ProcId:DWORD = $FFFFFFFF);
begin
ZeroMemory(scanInfo, SizeOf(TScanHookInfo));
MoveMemory(@scanInfo.ModuleName, PChar(ModuleName), Length(ModuleName)*sizeof(Char));
MoveMemory(@scanInfo.ModulePath, PChar(ModulePath), Length(ModulePath)*sizeof(Char));
scanInfo.ModuleBase:=ModuleBase;
scanInfo.Mode:=Mode;
if ProcId <> $FFFFFFFF then
scanInfo.ProcessId:=ProcId;
end;
function CheckInlineHook(scanInfo:PScanHookInfo):Boolean;
var
MapModuleBase :DWORD;
tempStr :string;
tempFile :string;
label lbExit1;
begin
Result:=False;
// 用户界面回显
tempStr:=Format('[%s]准备初始化',[string(scanInfo.ModuleName)]);
SendMessage(MainForm.Handle, MSG_THREAD_STATUS, Integer(@tempStr[1]), 0);
// 在这里,我将原文件拷贝到了临时目录再进行映射
tempFile:=CopyFileToTempDirectory(scanInfo.ModulePath);
if not FileExists(tempFile) then Exit;
// 映射模块
MapModuleBase:=DWORD(MapFileWriteAble(tempFile));
if MapModuleBase = 0 then
begin
tempStr:=Format('[%s]映射模块发生错误',[string(scanInfo.ModuleName)]);
SendMessage(MainForm.Handle, MSG_THREAD_ERROR, Integer(@tempStr[1]), 0);
Exit;
end;
// 用户界面回显
tempStr:=Format('[%s]初始化完毕,重定向数据...',[string(scanInfo.ModuleName)]);
SendMessage(MainForm.Handle, MSG_THREAD_STATUS, Integer(@tempStr[1]), 0);
// 重定向模块
if not RelocSpecialModule(MapModuleBase, scanInfo.ModuleBase) then
begin
tempStr:=Format('[%s]重定向模块时发生错误',[string(scanInfo.ModuleName)]);
SendMessage(MainForm.Handle, MSG_THREAD_ERROR, Integer(@tempStr[1]), 0);
goto lbExit1;
end;
// 填充结构
scanInfo.MapModuleBase :=MapModuleBase;
// 首先检测IATHook
case scanInfo.Mode of
KernelMode:
begin
CheckSpecialModuleIATHookKernel(scanInfo);
end;
UserMode:
begin
//CheckSpecialModuleIATHookUser(scanInfo);
end;
end;
// 扫描.text PAGE节区
ScanSection('.text', scaninfo);
ScanSection('PAGE', scaninfo);
Result:=True;
lbExit1:
if MapModuleBase <> 0 then UnMapFile(PBYTE(MapModuleBase));
DeleteFile(tempFile);
end;
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
上传的附件: