通過TEB遍歷程式模組

逗比汪星人發表於2013-04-03

#include "StdAfx.h"
#include <iostream>
#include <tchar.h>
#include <windows.h>

typedef struct _PEB_LDR_DATA {
	UINT Length;
	BYTE Initialized;
	void* SsHandle;
	LIST_ENTRY InLoadOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;

typedef struct _PEB {
	BYTE InheritedAddressSpace;
	BYTE ReadImageFileExecOptions;
	BYTE BeingDebugged;
	BYTE BitField;
	void* Mutant;
	void* ImageBaseAddress;
	PPEB_LDR_DATA Ldr;
} PEB, *PPEB;

typedef struct _CLIENT_ID {
	PVOID UniqueProcess;
	PVOID UniqueThread;
} CLIENT_ID, *PCLIENT_ID;

typedef struct _TEB {
	NT_TIB                  Tib;
	PVOID                   EnvironmentPointer;
	CLIENT_ID               Cid;
	PVOID                   ActiveRpcInfo;
	PVOID                   ThreadLocalStoragePointer;
	PPEB                    Peb;
} TEB, *PTEB;

typedef PTEB (NTAPI* FuncNtCurrentTeb)();

typedef struct _UNICODE_STRING {
	USHORT  Length;
	USHORT  MaximumLength;
	PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _LDR_DATA_TABLE_ENTRY {
	LIST_ENTRY  InLoadOrderLinks;
	LIST_ENTRY  InMemoryOrderModuleList;
	LIST_ENTRY  InInitializationOrderModuleList;
	PVOID  DllBase;
	PVOID  EntryPoint;
	ULONG  SizeOfImage;
	UNICODE_STRING FullDllName;
	UNICODE_STRING  BaseDllName;
} _LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

char * w2c(char *pcstr,const wchar_t *pwstr, size_t len)
{
	int nlength=wcslen(pwstr);
	
	//獲取轉換後的長度
	int nbytes = WideCharToMultiByte( 0, // specify the code page used to perform the conversion
		0,         // no special flags to handle unmapped characters
		pwstr,     // wide character string to convert
		nlength,   // the number of wide characters in that string
		NULL,      // no output buffer given, we just want to know how long it needs to be
		0,
		NULL,      // no replacement character given
		NULL );    // we don't want to know if a character didn't make it through the translation
	// make sure the buffer is big enough for this, making it larger if necessary
	if(nbytes>len)   
		nbytes=len;
	
	// 通過以上得到的結果,轉換unicode 字元為ascii 字元
	WideCharToMultiByte( 0, // specify the code page used to perform the conversion
		0,         // no special flags to handle unmapped characters
		pwstr,   // wide character string to convert
		nlength,   // the number of wide characters in that string
		pcstr, // put the output ascii characters at the end of the buffer
		nbytes,                           // there is at least this much space there
		NULL,      // no replacement character given
		NULL );
	return pcstr ;
}

void Show()
{
	FuncNtCurrentTeb ngt = (FuncNtCurrentTeb)GetProcAddress( GetModuleHandle( _T("ntdll.dll") ), "NtCurrentTeb" );
	PTEB pTeb = ngt();
	PPEB pPeb = pTeb->Peb;
	PPEB_LDR_DATA pPld = pPeb->Ldr;
	PLDR_DATA_TABLE_ENTRY pldte = (PLDR_DATA_TABLE_ENTRY)pPld->InLoadOrderModuleList.Flink;
	bool bFound = false;
	while( !bFound && pldte->DllBase != NULL )
	{
		char szDll[MAX_PATH];
		memset(szDll,0x00,MAX_PATH);
		w2c(szDll,pldte->BaseDllName.Buffer,pldte->BaseDllName.Length);
		_tprintf( _T("%s\r\n"),szDll);
		pldte = (PLDR_DATA_TABLE_ENTRY)((LIST_ENTRY*)(pldte))->Flink;
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	getchar();
	Show();
	getchar();
	Show();
	return 0;
}


相關文章