const WCHAR SourceString[]=L"\\SystemRoot\\system32\\ntdll.dll";
char aNtCreateProcess[]="NtCreateProcess";
void op_ntdll()
{
NTSTATUS status=STATUS_SUCCESS;
IMAGE_NT_HEADERS32 nt_headers; //var_1e4
char name[0x32];
IMAGE_SECTION_HEADER section_header; //var_b8
IMAGE_EXPORT_DIRECTORY image_export; //var_90
UNICODE_STRING DestinationString;
OBJECT_ATTRIBUTES ObjectAttributes;
ULONG AddressOfName;
ULONG file_AddressOfFunctions;
ULONG file_AddressOfNameOrdinals;
ULONG file_AddressOfNames;
IO_STATUS_BLOCK IoStatusBlock;
ULONG Buffer=0;//initialize before use
HANDLE FileHandle;
LARGE_INTEGER ByteOffset;
ULONG i;
RtlInitUnicodeString(&DestinationString,SourceString);
ObjectAttributes.ObjectName=&DestinationString;
ObjectAttributes.Length=0x18;
ObjectAttributes.RootDirectory=NULL;
ObjectAttributes.Attributes=0x240;
ObjectAttributes.SecurityDescriptor=NULL;
ObjectAttributes.SecurityQualityOfService=NULL;
status=ZwOpenFile(&FileHandle,GENERIC_READ,&ObjectAttributes,&IoStatusBlock,FILE_SHARE_READ,0x20);
if(status==STATUS_SUCCESS)
{
KdPrint(("open file %wZ successfully!e\n",&DestinationString));
ByteOffset.LowPart=0x3c;
ByteOffset.HighPart=0;
ZwReadFile(FileHandle,NULL,NULL,NULL,&IoStatusBlock,&Buffer,2,&ByteOffset,0);
KdPrint(("file_3c is 0x%08x\n",Buffer));
ByteOffset.LowPart=Buffer;
ZwReadFile(FileHandle,NULL,NULL,NULL,&IoStatusBlock,&nt_headers,0xf8,&ByteOffset,0);
KdPrint(("PE mark--->0x%08x\n",nt_headers.Signature));
if(nt_headers.Signature==IMAGE_NT_SIGNATURE)
{
Buffer+=0xf8;
if(nt_headers.FileHeader.NumberOfSections)
{
KdPrint(("ntdll.dll has 0x%x sections.\n",nt_headers.FileHeader.NumberOfSections));
do
{
ByteOffset.LowPart=Buffer;
ByteOffset.HighPart=0;
ZwReadFile(FileHandle,NULL,NULL,NULL,&IoStatusBlock,§ion_header,IMAGE_SIZEOF_SECTION_HEADER,&ByteOffset,0);
KdPrint(("VirtualAddress of image export is 0x%08x\n",nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress));
if(nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress>=section_header.VirtualAddress)
{
if(nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress<section_header.VirtualAddress+section_header.Misc.VirtualSize)
{
KdPrint(("the export table is located in %s.\n",section_header.Name));
ByteOffset.LowPart=nt_headers.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress-section_header.VirtualAddress+section_header.PointerToRawData;
ZwReadFile(FileHandle,NULL,NULL,NULL,&IoStatusBlock,&image_export,IMAGE_EXPORT_DIRECTORY_SIZE,&ByteOffset,0);
KdPrint(("image_export.NumberOfFunctions is 0x%x\n",image_export.NumberOfFunctions));
file_AddressOfNames=image_export.AddressOfNames-section_header.VirtualAddress+section_header.PointerToRawData;
file_AddressOfFunctions=image_export.AddressOfFunctions-section_header.VirtualAddress+section_header.PointerToRawData;
file_AddressOfNameOrdinals=image_export.AddressOfNameOrdinals-section_header.VirtualAddress+section_header.PointerToRawData;
if(image_export.NumberOfNames)
{
i=image_export.NumberOfNames;
do
{
ByteOffset.LowPart=file_AddressOfNames;
ZwReadFile(FileHandle,NULL,NULL,NULL,&IoStatusBlock,&AddressOfName,4,&ByteOffset,0);
AddressOfName=AddressOfName-section_header.VirtualAddress+section_header.PointerToRawData;
ByteOffset.LowPart=AddressOfName;
ZwReadFile(FileHandle,NULL,NULL,NULL,&IoStatusBlock,name,0x32,&ByteOffset,0);
// KdPrint(("func name is %s\n",name));
if(0==ansi_string_compare(aNtCreateProcess,name,ansi_string_length(aNtCreateProcess)))
KdPrint(("NtCreateProcess is found!\n"));
file_AddressOfNames+=0x4;
}while(--i);
}
break;
}
}
else
{
Buffer+=IMAGE_SIZEOF_SECTION_HEADER;
}
}while(--nt_headers.FileHeader.NumberOfSections);
}
}
ZwClose(FileHandle);
}
else
{
KdPrint(("error:0x%08x\n",status));
}
}
ULONG ansi_string_compare(char *stra,char *strb,ULONG Length)
{
if(strb!=NULL&&Length)
{
if(Length==ansi_string_length(strb))
{
do
{
if(*stra!=*strb)
break;
stra++;
strb++;
Length--;
}while(Length);
}
}
return Length;
}
ULONG ansi_string_length(char *str)
{
int length=0;
if(str!=NULL)
{
while(*str&&length<0x100)
{
length++;
str++;
}
}
return length;
}