在ntdll.dll中找到NtCreateProcess(***)

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,&section_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;
}

pe练习本

//从文件解析导入表,支持32/64pe

void op_ntdll()
{
	NTSTATUS                status = STATUS_SUCCESS;
	IMAGE_NT_HEADERS64      NtHeaders64;      //var_1e4
	IMAGE_NT_HEADERS32      NtHeaders32;
	DWORD              Signature = 0;//image_nt_headers Signature
	IMAGE_FILE_HEADER  FileHeader = { 0 };
	DWORD              NtHeadersSize = 0;
	DWORD              ExportDirVA = 0;
	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                   AddressOfNewExe = 0;//initialize before use
	HANDLE                  FileHandle;
	LARGE_INTEGER           ByteOffset;
	ULONG                   i;

	RtlInitUnicodeString(&DestinationString, SourceString);
	ObjectAttributes.ObjectName = &DestinationString;
	ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
	ObjectAttributes.RootDirectory = NULL;
	ObjectAttributes.Attributes = 0x240;
	ObjectAttributes.SecurityDescriptor = NULL;
	ObjectAttributes.SecurityQualityOfService = NULL;

	FileHandle=CreateFileW(SourceString, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (FileHandle)
	{
		printf("open file %wZ successfully!e\n", &DestinationString);
		ByteOffset.LowPart = 0x3c;//get e_lfanew
		ByteOffset.HighPart = 0;
		NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, &AddressOfNewExe, 2, &ByteOffset, 0);
		printf("file_3c is 0x%08x\n", AddressOfNewExe);

		ByteOffset.LowPart = AddressOfNewExe;
		NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, &Signature, 0x4, &ByteOffset, 0);
		printf("PE mark--->0x%08x\n", Signature);
		if (Signature != IMAGE_NT_SIGNATURE)
			return;

		ByteOffset.LowPart = AddressOfNewExe+4;
		NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, &FileHeader, sizeof(IMAGE_FILE_HEADER), &ByteOffset, 0);
		if (FileHeader.NumberOfSections)
		{
			printf("ntdll.dll has 0x%x sections.\n", FileHeader.NumberOfSections);
		}
		else
		{
			return;
		}
		//the difference between pe32 and pe64 is the optional header
		//
		//under pe32,address length is 4
		//
		//under pe64,address length is 8
		//
		if (FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
		{
			printf("FileHeader.Machine:0x%x,it is a pe32.\n",FileHeader.Machine);
			NtHeadersSize = sizeof(IMAGE_NT_HEADERS32);

			ByteOffset.LowPart = AddressOfNewExe;
			NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, &NtHeaders32, NtHeadersSize, &ByteOffset, 0);

			ExportDirVA = NtHeaders32.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
		}
		else if (FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
		{
			printf("FileHeader.Machine:0x%x,it is a pe64.\n", FileHeader.Machine);
			NtHeadersSize = sizeof(IMAGE_NT_HEADERS64);
			ByteOffset.LowPart = AddressOfNewExe;
			NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock,&NtHeaders64, NtHeadersSize, &ByteOffset, 0);


			ExportDirVA = NtHeaders64.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
		}
		else
		{
			printf("unknown file format!\n");
			return;
		}

		printf("VirtualAddress of image export is 0x%08x\n", ExportDirVA);
		do
		{
			ByteOffset.LowPart = AddressOfNewExe+NtHeadersSize;
			ByteOffset.HighPart = 0;
			//read section header
			NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, &section_header, IMAGE_SIZEOF_SECTION_HEADER, &ByteOffset, 0);
			printf("section name:%s\n", section_header.Name);
				    
			if (ExportDirVA >= section_header.VirtualAddress)
			{
				if (ExportDirVA < section_header.VirtualAddress + section_header.Misc.VirtualSize)
				{
				    printf("the export table is located in %s.\n", section_header.Name);
					ByteOffset.LowPart = ExportDirVA - section_header.VirtualAddress + section_header.PointerToRawData;
					//read export dir
					NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, &image_export, sizeof(IMAGE_EXPORT_DIRECTORY), &ByteOffset, 0);
                    printf("image_export.NumberOfFunctions is 0x%x\n", image_export.NumberOfFunctions);

					//here it reads the raw data from the file not in the memory
					//
					//first get the names's offset in the raw data
					//
					//second read the raw data from file
					//
					//
					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;
							NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, &AddressOfName, 4, &ByteOffset, 0);
							AddressOfName = AddressOfName - section_header.VirtualAddress + section_header.PointerToRawData;
							ByteOffset.LowPart = AddressOfName;
							NtReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock, name, 0x32, &ByteOffset, 0);
							//printf("func name is %s\n",name);
							if (0 == ansi_string_compare(aNtCreateProcess, name, ansi_string_length(aNtCreateProcess)))
									printf("%s is found!\n",name);
							if (0x3B1B637B == loop_right_move((byte*)name, 0xd))
							{
								printf("name:%s\n", name);
							}
							file_AddressOfNames += 0x4;
						} while (--i);
					}
					break;
				}
			}
			AddressOfNewExe += IMAGE_SIZEOF_SECTION_HEADER;
		} while (--FileHeader.NumberOfSections);
		NtClose(FileHandle);
	}
	else
	{
		printf("CreateFileW fails,error:0x%08x\n", GetLastError());
	}
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值