C 转 Delphi 过程中出现一个问题.[200分](200分)

  • 主题发起人 全文检索
  • 开始时间

全文检索

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
IMAGE_FIXUP_ENTRY = packed record
offset:WORD;
types:WORD;
end;
PIMAGE_FIXUP_ENTRY = ^IMAGE_FIXUP_ENTRY;
NTSTATUS = LongWord;

type
_SYSTEM_MODULE_INFORMATION = packed record
Reserved:Array[0..1] of LongWord;
Base:pointer;
Size:LongWord;
Flags:LongWord;
Index:WORD;
Unknown:WORD;
LoadCount:WORD;
ModuleNameOffset:WORD;
ImageName:Array[0..255] of char;
end;

type
MODULES = packed record
dwNumberOfModules:DWORD;
smi:_SYSTEM_MODULE_INFORMATION;
end;

TPMODULES = ^MODULES;


SYSTEM_MODULE_INFORMATION = _SYSTEM_MODULE_INFORMATION;
PSYSTEM_MODULE_INFORMATION = ^SYSTEM_MODULE_INFORMATION;

type
TPDWord = ^DWORD;

TSystem_Basic_Information = packed record
dwUnknown1: DWORD;
uKeMaximumIncrement: ULONG;
uPageSize: ULONG;
uMmNumberOfPhysicalPages: ULONG;
uMmLowestPhysicalPage: ULONG;
uMmHighestPhysicalPage: ULONG;
uAllocationGranularity: ULONG;
pLowestUserAddress: Pointer;
pMmHighestUserAddress: Pointer;
uKeActiveProcessors: ULONG;
bKeNumberProcessors: byte;
bUnknown2: byte;
wUnknown3: word;
end;
var
Form1: TForm1;

NtQuerySystemInformation: function(infoClass: DWORD;
buffer: Pointer;
bufSize: DWORD;
returnSize: TPDword): DWORD
stdcall = nil;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
pModules: TPMODULES;
p:pointer;
STATUS_INFO_LENGTH_MISMATCH:dword;
rc,dwNeededSize:Dword;

dwKernelBase:dword;
pKernelName:string;
hKernel:HMODULE;
begin
STATUS_INFO_LENGTH_MISMATCH:=$C0000004;
if @NtQuerySystemInformation = nil then
NtQuerySystemInformation := GetProcAddress(GetModuleHandle('ntdll.dll'),'NtQuerySystemInformation');
if @NtQuerySystemInformation = nil then exit;
rc:=NtQuerySystemInformation(11,@pModules, 4,@dwNeededSize);

if rc = STATUS_INFO_LENGTH_MISMATCH then
begin
pModules:=TPMODULES(GlobalAlloc(GPTR,dwNeededSize));
rc:=NtQuerySystemInformation(11,@pModules,dwNeededSize,nil);
end;
if rc=0 then exit;
dwKernelBase:=dword(pModules.smi.Base)
//这里的 pModules.smi.Base 数据为 0
pKernelName:=pModules.smi.ModuleNameOffset+pModules.smi.ImageName
//这里 pKernelName = '' 所以下面那句不会成功
hKernel:=LoadLibraryEx(pchar(pKernelName),0,DONT_RESOLVE_DLL_REFERENCES);
end;

end.

//下面是 VC 的原文
 
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <shlwapi.h>



#define IOCTL_SETPROC (ULONG)CTL_CODE( FILE_DEVICE_UNKNOWN, 0x852, METHOD_NEITHER, FILE_READ_DATA | FILE_WRITE_DATA )

#define RVATOVA(base,offset) ((PVOID)((DWORD)(base)+(DWORD)(offset)))
#define ibaseDD *(PDWORD)&amp;ibase
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)

typedef struct {
WORD offset:12;
WORD type:4;
} IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;

typedef LONG NTSTATUS;

typedef NTSTATUS (WINAPI *PFNNtQuerySystemInformation)(
DWORD SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);

typedef struct _SYSTEM_MODULE_INFORMATION {//Information Class 11
ULONG Reserved[2];
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
}SYSTEM_MODULE_INFORMATION,*PSYSTEM_MODULE_INFORMATION;

typedef struct {
DWORD dwNumberOfModules;
SYSTEM_MODULE_INFORMATION smi;
} MODULES, *PMODULES;


BOOL SetProc( IN HANDLE hDriver, IN ULONG ulIndex, IN PULONG buf )
{
if ( NULL == buf )
{
return FALSE;
}
DWORD dwReturned;
BOOL bRet = DeviceIoControl( hDriver, IOCTL_SETPROC, &amp;ulIndex,sizeof( ULONG ), buf, sizeof( ULONG ), &amp;dwReturned, NULL );
return bRet &amp;&amp
ERROR_SUCCESS == GetLastError();
}


DWORD GetHeaders(PCHAR ibase,
PIMAGE_FILE_HEADER *pfh,
PIMAGE_OPTIONAL_HEADER *poh,
PIMAGE_SECTION_HEADER *psh)

{
PIMAGE_DOS_HEADER mzhead=(PIMAGE_DOS_HEADER)ibase;

if ((mzhead->e_magic!=IMAGE_DOS_SIGNATURE) ||
(ibaseDD[mzhead->e_lfanew]!=IMAGE_NT_SIGNATURE))
return FALSE;

*pfh=(PIMAGE_FILE_HEADER)&amp;ibase[mzhead->e_lfanew];
if (((PIMAGE_NT_HEADERS)*pfh)->Signature!=IMAGE_NT_SIGNATURE)
return FALSE;
*pfh=(PIMAGE_FILE_HEADER)((PBYTE)*pfh+sizeof(IMAGE_NT_SIGNATURE));

*poh=(PIMAGE_OPTIONAL_HEADER)((PBYTE)*pfh+sizeof(IMAGE_FILE_HEADER));
if ((*poh)->Magic!=IMAGE_NT_OPTIONAL_HDR32_MAGIC)
return FALSE;

*psh=(PIMAGE_SECTION_HEADER)((PBYTE)*poh+sizeof(IMAGE_OPTIONAL_HEADER));
return TRUE;
}


DWORD FindKiServiceTable(HMODULE hModule,DWORD dwKSDT)
{
PIMAGE_FILE_HEADER pfh;
PIMAGE_OPTIONAL_HEADER poh;
PIMAGE_SECTION_HEADER psh;
PIMAGE_BASE_RELOCATION pbr;
PIMAGE_FIXUP_ENTRY pfe


DWORD dwFixups=0,i,dwPointerRva,dwPointsToRva,dwKiServiceTable;
BOOL bFirstChunk;

GetHeaders((PCHAR)hModule,&amp;pfh,&amp;poh,&amp;psh);

// loop thru relocs to speed up the search
if ((poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) &amp;&amp;
(!((pfh->Characteristics)&amp;IMAGE_FILE_RELOCS_STRIPPED))) {

pbr=(PIMAGE_BASE_RELOCATION)RVATOVA(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress,hModule);

bFirstChunk=TRUE;
// 1st IMAGE_BASE_RELOCATION.VirtualAddress of ntoskrnl is 0
while (bFirstChunk || pbr->VirtualAddress) {
bFirstChunk=FALSE;

pfe=(PIMAGE_FIXUP_ENTRY)((DWORD)pbr+sizeof(IMAGE_BASE_RELOCATION));

for (i=0;i<(pbr->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))>>1;i++,pfe++) {
if (pfe->type==IMAGE_REL_BASED_HIGHLOW) {
dwFixups++;
dwPointerRva=pbr->VirtualAddress+pfe->offset;
// DONT_RESOLVE_DLL_REFERENCES flag means relocs aren't fixed
dwPointsToRva=*(PDWORD)((DWORD)hModule+dwPointerRva)-(DWORD)poh->ImageBase;

// does this reloc point to KeServiceDescriptorTable.Base?
if (dwPointsToRva==dwKSDT) {
// check for mov [mem32],imm32. we are trying to find
// "mov ds:_KeServiceDescriptorTable.Base, offset _KiServiceTable"
// from the KiInitSystem.
if (*(PWORD)((DWORD)hModule+dwPointerRva-2)==0x05c7) {
// should check for a reloc presence on KiServiceTable here
// but forget it
dwKiServiceTable=*(PDWORD)((DWORD)hModule+dwPointerRva+4)-poh->ImageBase;
return dwKiServiceTable;
}
}

} else
if (pfe->type!=IMAGE_REL_BASED_ABSOLUTE)
// should never get here
printf("/trelo type %d found at .%X/n",pfe->type,pbr->VirtualAddress+pfe->offset);
}
*(PDWORD)&amp;pbr+=pbr->SizeOfBlock;
}
}

if (!dwFixups)
// should never happen - nt, 2k, xp kernels have relocation data
printf("No fixups!/n");
return 0;
}

void ReSSDT( IN HANDLE hDriver)
{
HMODULE hKernel;
DWORD dwKSDT
// rva of KeServiceDescriptorTable
DWORD dwKiServiceTable
// rva of KiServiceTable
PMODULES pModules=(PMODULES)&amp;pModules;
DWORD dwNeededSize,rc;
DWORD dwKernelBase,dwServices=0;
PCHAR pKernelName;
PDWORD pService;
PIMAGE_FILE_HEADER pfh;
PIMAGE_OPTIONAL_HEADER poh;
PIMAGE_SECTION_HEADER psh;


FARPROC NtQuerySystemInformationAddr=GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQuerySystemInformation");
// get system modules - ntoskrnl is always first there
rc=((PFNNtQuerySystemInformation)NtQuerySystemInformationAddr)(11,pModules,4,&amp;dwNeededSize);
if (rc==STATUS_INFO_LENGTH_MISMATCH) {
pModules=(MODULES *)GlobalAlloc(GPTR,dwNeededSize);
rc=((PFNNtQuerySystemInformation)NtQuerySystemInformationAddr)(11,pModules,dwNeededSize,NULL);
} else {
strange:
printf("strange NtQuerySystemInformation()!/n");
return;
}
if (!NT_SUCCESS(rc)) goto strange;

// imagebase
dwKernelBase=(DWORD)pModules->smi.Base;
// filename - it may be renamed in the boot.ini
pKernelName=pModules->smi.ModuleNameOffset+pModules->smi.ImageName;

// map ntoskrnl - hopefully it has relocs
hKernel=LoadLibraryEx(pKernelName,0,DONT_RESOLVE_DLL_REFERENCES);
if (!hKernel) {
printf("Failed to load! LastError=%i/n",GetLastError());
return

}

GlobalFree(pModules);

// our own export walker is useless here - we have GetProcAddress :)
if (!(dwKSDT=(DWORD)GetProcAddress(hKernel,"KeServiceDescriptorTable"))) {
printf("Can't find KeServiceDescriptorTable/n");
return;
}

// get KeServiceDescriptorTable rva
dwKSDT-=(DWORD)hKernel

// find KiServiceTable
if (!(dwKiServiceTable=FindKiServiceTable(hKernel,dwKSDT))) {
printf("Can't find KiServiceTable.../n");
return;
}

printf("&amp;KiServiceTable==%08X/n/nDumping 'old' ServiceTable:/n/n",dwKiServiceTable+dwKernelBase)


// let's dump KiServiceTable contents

// MAY FAIL!!!
// should get right ServiceLimit here, but this is trivial in the kernel mode
GetHeaders((PCHAR)hKernel,&amp;pfh,&amp;poh,&amp;psh);

for (pService=(PDWORD)((DWORD)hKernel+dwKiServiceTable);
*pService-poh->ImageBase<poh->SizeOfImage;
pService++,dwServices++)
{
ULONG ulAddr=*pService-poh->ImageBase+dwKernelBase;
SetProc( hDriver,dwServices, &amp;ulAddr );
//printf("%08X/n",ulAddr)

}


printf("/n/nPossibly KiServiceLimit==%08X/n",dwServices);

FreeLibrary(hKernel);

}


BOOL GetDriverPath( OUT LPTSTR lpFileName, IN DWORD dwSize )
{
// &amp;Egrave;·&amp;para;¨&amp;Ccedil;&amp;yacute;&amp;para;&amp;macr;&amp;Icirc;&amp;raquo;&amp;Ouml;&amp;Atilde;
TCHAR szPath[MAX_PATH];
GetModuleFileName( NULL, szPath, MAX_PATH );
lstrcpy( _tcsrchr( szPath, _T('//') ) + 1, _T("RESSDT.sys") );

lstrcpyn( lpFileName, szPath, dwSize );

return PathFileExists( lpFileName );
}

HANDLE LoadDriver( IN LPCTSTR lpFileName )
{
HANDLE hDriver = INVALID_HANDLE_VALUE;
SC_HANDLE hSCManager = OpenSCManager( NULL, NULL,
SC_MANAGER_CREATE_SERVICE );
if ( NULL != hSCManager )
{
SC_HANDLE hService = CreateService( hSCManager, _T("RESSDT"),
_T("RESSDT"), SERVICE_START,
SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
SERVICE_ERROR_IGNORE, lpFileName, NULL, NULL, NULL, NULL, NULL );
if ( ERROR_SERVICE_EXISTS == GetLastError() )
{
hService = OpenService( hSCManager, _T("RESSDT"), SERVICE_START );
}
StartService(hService,0,NULL);


hDriver = CreateFileA( "////.//RESSDTDOS",
GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );

CloseServiceHandle( hService );
CloseServiceHandle( hSCManager );
}

return hDriver;
}

void UnloadDriver( IN HANDLE hDriver )
{
CloseHandle( hDriver );

SC_HANDLE hSCManager = OpenSCManager( NULL, NULL,SC_MANAGER_CREATE_SERVICE );
if ( NULL != hSCManager )
{
SC_HANDLE hService = OpenService( hSCManager, _T("RESSDT"), DELETE | SERVICE_STOP );
if ( NULL != hService )
{
SERVICE_STATUS ss;
ControlService( hService, SERVICE_CONTROL_STOP, &amp;ss );
DeleteService( hService );
CloseServiceHandle( hService );
}
CloseServiceHandle( hSCManager );
}
}

int main( void )
{
TCHAR strDriver[MAX_PATH];

GetDriverPath(strDriver,MAX_PATH);

printf("%s /n",strDriver);

HANDLE hDriver = LoadDriver( strDriver );
if ( INVALID_HANDLE_VALUE == hDriver )
{
puts( "Load driver failed!" );
return -1;
}


ReSSDT(hDriver);


UnloadDriver( hDriver );

return EXIT_SUCCESS;
}
 
做成dll调调么好类,
 
期待中.........
 
FARPROC NtQuerySystemInformationAddr=GetProcAddress(GetModuleHandle("ntdll.dll"),"NtQuerySystemInformation");
// get system modules - ntoskrnl is always first there
rc=((PFNNtQuerySystemInformation)NtQuerySystemInformationAddr)(11,pModules,4,&amp;dwNeededSize);
if (rc==STATUS_INFO_LENGTH_MISMATCH) {
pModules=(MODULES *)GlobalAlloc(GPTR,dwNeededSize);
rc=((PFNNtQuerySystemInformation)NtQuerySystemInformationAddr)(11,pModules,dwNeededSize,NULL);
//===================================
注意这里:
原程序调用了2次,为pModules分配了内存空间。
可是lz却没有为它分配内存。
例如:(修改了下)
TPWord = ^DWORD;
buf:TPWord;
buf := AllocMem(dwNeededSize* 2);
NtQuerySystemInformation(11, buf, numBytes * 2, @dwNeededSize);
如果分配内存,可以得到所有的驱动信息,调试通过。
lz在看看
 
baiduan 能把你调试通过的代码贴出来吗?

buf := AllocMem(dwNeededSize* 2)
//dwNeededSize 还没有值,是不是在调用一次NtQuerySystemInformation 之后,那第一次要怎么写.

你新增了一个变量 numBytes 这个值又是多少.

NtQuerySystemInformation 成功返回 0 .我怎么都不能返回成功.
 
多人接受答案了。
 
顶部