能力值:
( LV2,RANK:10 )
|
-
-
2 楼
// test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Windows.h>
#include <WinNT.h>
#include <stdio.h>
#include <conio.h>
#include "tools.h"
int main(int argc, char* argv[])
{
try{
HANDLE hFile=CreateFile("core.dll",GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
printf("hFile=%d\n",hFile);
if (hFile==INVALID_HANDLE_VALUE){
throw "hFile==INVALID_HANDLE_VALUE";
}
try{
DWORD dwFileSize=GetFileSize(hFile,NULL);
printf("dwFileSize=%d\n",dwFileSize);
if (!dwFileSize){
throw "dwFileSize==0";
}
try{
HANDLE hFileMapping=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL);
printf("hFileMapping=%d\n",hFileMapping);
if (hFileMapping==INVALID_HANDLE_VALUE){
throw "hFileMapping==INVALID_HANDLE_VALUE";
}
try{
void *pFileMapping=MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0);
printf("pFileMapping=%d\n",pFileMapping);
if (!pFileMapping){
throw "pFileMapping==0";
}
try{
PIMAGE_DOS_HEADER pDosHeader;
pDosHeader=(PIMAGE_DOS_HEADER)pFileMapping;
if (pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE){
throw "pDosHeader->e_magic!=IMAGE_DOS_SIGNATURE";
}
printf("pDosHeader->e_magic==IMAGE_DOS_SIGNATURE\n");
printf("pDosHeader->e_lfanew=%d\n",pDosHeader->e_lfanew);
DWORD *pPeFlag=(DWORD *)((DWORD)pFileMapping+pDosHeader->e_lfanew);
if (*pPeFlag!=IMAGE_NT_SIGNATURE){
throw "*pPeFlag!=IMAGE_NT_SIGNATURE";
}
printf("*pPeFlag==IMAGE_NT_SIGNATURE\n");
PIMAGE_FILE_HEADER pPeHeader=(PIMAGE_FILE_HEADER)((DWORD)pPeFlag+sizeof(DWORD));
pPeHeader->NumberOfSections;
printf("NumOfSections=%d\n",pPeHeader->NumberOfSections);
PIMAGE_OPTIONAL_HEADER pOptionalHeader=(PIMAGE_OPTIONAL_HEADER)((DWORD)pPeHeader+sizeof(IMAGE_FILE_HEADER));
if (pOptionalHeader->Magic!=0x010B){
throw "pOptionalHeader->Magic!=0x010B";
}
printf("pOptionalHeader->Magic==0x010B\n");
printf("SizeOfImage=%d\n",pOptionalHeader->SizeOfImage);
printf("SizeOfHeaders=%d\n",pOptionalHeader->SizeOfHeaders);
printf("SizeOfCode=%d\n",pOptionalHeader->SizeOfCode);
printf("FileAlignment=%d\n",pOptionalHeader->FileAlignment);
printf("SectionAlignment=%d\n",pOptionalHeader->SectionAlignment);
printf("AddressOfEntryPoint=%d(RVA)\n",pOptionalHeader->AddressOfEntryPoint);
HANDLE hMemoryExec=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_EXECUTE_READWRITE,0,pOptionalHeader->SizeOfImage,NULL);
printf("hMemoryExec=%d\n",hMemoryExec);
if (hMemoryExec==INVALID_HANDLE_VALUE){
throw "hMemoryExec==INVALID_HANDLE_VALUE";
}
try{
void *pMemoryExec=MapViewOfFile(hMemoryExec,FILE_MAP_WRITE,0,0,0);
printf("pMemoryExec=%d\n",pMemoryExec);
if (!pMemoryExec){
throw "pMemoryExec==0";
}
try{
memcpy(pMemoryExec,pFileMapping,pOptionalHeader->SizeOfHeaders);
PIMAGE_SECTION_HEADER pIMAGE_SECTION_HEADER=(PIMAGE_SECTION_HEADER)((DWORD)pOptionalHeader+sizeof(IMAGE_OPTIONAL_HEADER));
UINT i;
for (i=0;i<pPeHeader->NumberOfSections;i++)
{
printf("SECTION Name=%s\n",pIMAGE_SECTION_HEADER[i].Name);
printf("PointerToRawData=%d\n",pIMAGE_SECTION_HEADER[i].PointerToRawData);
printf("SizeOfRawData=%d\n",pIMAGE_SECTION_HEADER[i].SizeOfRawData);
printf("VirtualAddress=%d(RAV)\n",pIMAGE_SECTION_HEADER[i].VirtualAddress);
if (pIMAGE_SECTION_HEADER[i].PointerToRawData){
memcpy((void *)((DWORD)pMemoryExec+pIMAGE_SECTION_HEADER[i].VirtualAddress),(void *)((DWORD)pFileMapping+pIMAGE_SECTION_HEADER[i].PointerToRawData),pIMAGE_SECTION_HEADER[i].SizeOfRawData);
}else{
memset((void *)((DWORD)pMemoryExec+pIMAGE_SECTION_HEADER[i].VirtualAddress),0,pIMAGE_SECTION_HEADER[i].SizeOfRawData);
}
}
PIMAGE_SECTION_HEADER psh;
PIMAGE_BASE_RELOCATION pBaseRelocation=(PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(pMemoryExec,IMAGE_DIRECTORY_ENTRY_BASERELOC,&psh);
printf("pBaseRelocation=%d\n",pBaseRelocation);
if (!pBaseRelocation){
throw "Can'not find IMAGE_DIRECTORY_ENTRY_BASERELOC";
}
printf("pBaseRelocation@SECTION %s\n",psh->Name);
UINT16 *pBL;
for (i=(pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size/4096)+1;i>0;i--){
pBL=(UINT16 *)((DWORD)pBaseRelocation+sizeof(IMAGE_BASE_RELOCATION));
for (DWORD j=1;j<=(pBaseRelocation->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/2;j++){
if (*pBL&0xF000){
printf("Found RELOCATION Block #%d\n",j);
printf("Base Address=%d(RVA)\n",pBaseRelocation->VirtualAddress);
printf("Offset=%d\n",*pBL&0x0FFF);
DWORD *Point=(DWORD *)((DWORD)pMemoryExec+pBaseRelocation->VirtualAddress+(*pBL&0x0FFF));
printf("Memary@%d\n",Point);
printf("Old Point=%d\n",*Point);
printf("New Point=%d\n",*Point+((DWORD)pMemoryExec)-pOptionalHeader->ImageBase);
*Point+=(((DWORD)pMemoryExec)-pOptionalHeader->ImageBase);
}
pBL++;
}
pBaseRelocation+=4096;
}
PIMAGE_IMPORT_DESCRIPTOR pImportedSymbols=(PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryOffset(pMemoryExec,IMAGE_DIRECTORY_ENTRY_IMPORT,&psh);
printf("pImportedSymbols=%d\n",pImportedSymbols);
if (!pImportedSymbols){
throw "Can'not find IMAGE_DIRECTORY_ENTRY_BASERELOC";
}
printf("pImportedSymbols@SECTION %s\n",psh->Name);
for (i=0;i<(pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size/sizeof(IMAGE_IMPORT_DESCRIPTOR));i++){
if (pImportedSymbols[i].Characteristics==0){
break;
}
printf("Found DLL Import %s\n",(char *)((DWORD)pMemoryExec+pImportedSymbols[i].Name));
DWORD * pImageThunkData=(DWORD *)((DWORD)pMemoryExec+pImportedSymbols[i].FirstThunk);
PIMAGE_IMPORT_BY_NAME pImageImportByName;
HMODULE hDll=LoadLibrary((char *)((DWORD)pMemoryExec+pImportedSymbols[i].Name));
if (!hDll){
throw "Can't load dll";
}
printf("Load Library %s ; HMODULE=%d\n",(char *)((DWORD)pMemoryExec+pImportedSymbols[i].Name),hDll);
do{
pImageImportByName=(PIMAGE_IMPORT_BY_NAME)((DWORD)pMemoryExec+*pImageThunkData);
printf("Found Function Import %s @ %d\n",pImageImportByName->Name,pImageImportByName);
*pImageThunkData=(ULONG)GetProcAddress(hDll,(char *)pImageImportByName->Name);
printf("Import %s @ %d\n",pImageImportByName->Name,*pImageThunkData);
pImageThunkData++;
}while(*pImageThunkData);
}
BOOL (__stdcall* entry)(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved);
entry=(BOOL (__stdcall *)(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved))((DWORD)pMemoryExec+pOptionalHeader->AddressOfEntryPoint);
printf("Run Exec @ %d\n",entry);
BOOL result=entry((HANDLE)1,(DWORD)1,(LPVOID)1);
printf("result=%d\n",result);
}catch(char *str){
printf("Exceptional %s\n",str);
}
UnmapViewOfFile(pMemoryExec);
}catch(char *str){
printf("Exceptional %s\n",str);
}
CloseHandle(hMemoryExec);
}catch(char *str){
printf("Exceptional %s\n",str);
}
UnmapViewOfFile(pFileMapping);
}catch (char *str){
printf("Exceptional %s\n",str);
}
CloseHandle(hFileMapping);
}catch(char *str){
printf("Exceptional %s\n",str);
}
}catch(char *str){
printf("Exceptional %s\n",str);
}
CloseHandle(hFile);
}catch(char *str){
printf("Exceptional %s\n",str);
}catch(...){
printf("Exceptional Unknow,LastError=%d\n",GetLastError());
}
printf("Exit\n");
return 0;
}
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
#pragma once
#include <WinNT.h>
#define SIZE_OF_NT_SIGNATURE sizeof(DWORD)
/* PE文件签名的偏移量。 */
#define NTSIGNATURE(a) ((LPVOID)((BYTE *)a + \
((PIMAGE_DOS_HEADER)a)->e_lfanew))
/* MS-OS头标示出NT的PE文件签名的dword;
PE文件头就存在于那个dword之后。 */
#define PEFHDROFFSET(a) ((LPVOID)((BYTE *)a + \
((PIMAGE_DOS_HEADER)a)->e_lfanew + \
SIZE_OF_NT_SIGNATURE))
/* PE可选头就在PE文件头的后面。 */
#define OPTHDROFFSET(a) ((LPVOID)((BYTE *)a + \
((PIMAGE_DOS_HEADER)a)->e_lfanew + \
SIZE_OF_NT_SIGNATURE + \
sizeof (IMAGE_FILE_HEADER)))
/* 节头就在PE可选头的后面。 */
#define SECHDROFFSET(a) ((LPVOID)((BYTE *)a + \
((PIMAGE_DOS_HEADER)a)->e_lfanew + \
SIZE_OF_NT_SIGNATURE + \
sizeof (IMAGE_FILE_HEADER) + \
sizeof (IMAGE_OPTIONAL_HEADER)))
typedef struct tagImportDirectory
{
DWORD dwRVAFunctionNameList; //函数名字列表的RVA
DWORD dwUseless1; //未用1
DWORD dwUseless2; //未用2
DWORD dwRVAModuleName; //模块名字的RVA
DWORD dwRVAFunctionAddressList; //函数地址列表的RVA
}IMAGE_IMPORT_MODULE_DIRECTORY,
* PIMAGE_IMPORT_MODULE_DIRECTORY;
DWORD ImageFileType (
LPVOID lpFile)
{
/* DOS文件签名先出现。 */
if (*(USHORT *)lpFile == IMAGE_DOS_SIGNATURE)
{
/* 从DOS头开始确定PE文件头的位置。 */
if (LOWORD (*(DWORD *)NTSIGNATURE (lpFile)) ==
IMAGE_OS2_SIGNATURE ||
LOWORD (*(DWORD *)NTSIGNATURE (lpFile)) ==
IMAGE_OS2_SIGNATURE_LE)
return (DWORD)LOWORD(*(DWORD *)NTSIGNATURE (lpFile));
else if (*(DWORD *)NTSIGNATURE (lpFile) ==
IMAGE_NT_SIGNATURE)
return IMAGE_NT_SIGNATURE;
else
return IMAGE_DOS_SIGNATURE;
}
else
/* 未知的文件类型。 */
return 0;
}
int NumOfSections (
LPVOID lpFile)
{
/* 文件头中标示的节的数量。 */
return (int)(((PIMAGE_FILE_HEADER) PEFHDROFFSET (lpFile))->NumberOfSections);
}
LPVOID GetModuleEntryPoint (
LPVOID lpFile)
{
PIMAGE_OPTIONAL_HEADER poh;
poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
if (poh != NULL)
return (LPVOID)poh->AddressOfEntryPoint;
else
return NULL;
}
BOOL GetSectionHdrByName (
LPVOID lpFile,
IMAGE_SECTION_HEADER *sh,
char *szSection)
{
PIMAGE_SECTION_HEADER psh;
int nSections = NumOfSections (lpFile);
int i;
if ((psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile)) !=
NULL)
{
/* 按名字寻找节 */
for (i=0; i<nSections; i++)
{
if (!strcmp ((const char *)psh->Name, szSection))
{
/* copy data to header */
CopyMemory ((LPVOID)sh,
(LPVOID)psh,
sizeof (IMAGE_SECTION_HEADER));
return TRUE;
}
else
psh++;
}
}
return FALSE;
}
LPVOID ImageDirectoryOffset (
LPVOID lpFile,
DWORD dwIMAGE_DIRECTORY,
PIMAGE_SECTION_HEADER *pSH)
{
PIMAGE_OPTIONAL_HEADER poh;
PIMAGE_SECTION_HEADER psh;
int nSections = NumOfSections (lpFile);
int i = 0;
LPVOID VAImageDir;
/* 检索出节头和可选头的偏移量。 */
poh = (PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET (lpFile);
psh = (PIMAGE_SECTION_HEADER)SECHDROFFSET (lpFile);
/* 一直到(NumberOfRvaAndSizes-1)都必须为0。 */
if (dwIMAGE_DIRECTORY >= poh->NumberOfRvaAndSizes)
return NULL;
/* 定位映像文件目录的相对虚拟地址。 */
VAImageDir = (LPVOID)poh->DataDirectory
[dwIMAGE_DIRECTORY].VirtualAddress;
/* 定位包含映像文件目录的节。 */
while (i++<nSections)
{
if (psh->VirtualAddress <= (DWORD)VAImageDir &&
psh->VirtualAddress +
psh->SizeOfRawData > (DWORD)VAImageDir)
break;
psh++;
}
if (i > nSections)
return NULL;
if (pSH)
*pSH=psh;
/* 返回映像文件输入目录的偏移量。 */
return (LPVOID)((int)lpFile +
(int)VAImageDir);
}
int WINAPI GetExportFunctionNames (
LPVOID lpFile,
HANDLE hHeap,
char **pszFunctions)
{
IMAGE_SECTION_HEADER sh;
PIMAGE_EXPORT_DIRECTORY ped;
char *pNames, *pCnt;
int i, nCnt;
/* 为.edata节取得节头和数据目录的指针。 */
if ((ped = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryOffset
(lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT,NULL)) == NULL)
return 0;
GetSectionHdrByName (lpFile, &sh, ".edata");
/* 确定输出函数名字的偏移量。 */
pNames = (char *)(*(int *)((int)ped->AddressOfNames -
(int)sh.VirtualAddress +
(int)sh.PointerToRawData +
(int)lpFile) -
(int)sh.VirtualAddress +
(int)sh.PointerToRawData +
(int)lpFile);
/* 计算所有字符串需分配多少内存。 */
pCnt = pNames;
for (i=0; i<(int)ped->NumberOfNames; i++)
while (*pCnt++);
nCnt = (int)(pCnt-pNames);
/* 从堆中为函数名字分配内存。 */
*pszFunctions = (char *)HeapAlloc (hHeap, HEAP_ZERO_MEMORY, nCnt);
/* 复制所有字符串到缓存区中。 */
CopyMemory ((LPVOID)*pszFunctions, (LPVOID)pNames, nCnt);
return nCnt;
}
int WINAPI GetImportModuleNames (
LPVOID lpFile,
HANDLE hHeap,
char **pszModules)
{
PIMAGE_IMPORT_MODULE_DIRECTORY pid;
IMAGE_SECTION_HEADER idsh;
BYTE *pData;
int nCnt = 0, nSize = 0, i;
char *pModule[1024];
char *psz;
pid = (PIMAGE_IMPORT_MODULE_DIRECTORY)ImageDirectoryOffset
(lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT,NULL);
pData = (BYTE *)pid;
/* 定位".idata"节的节头。 */
if (!GetSectionHdrByName (lpFile, &idsh, ".idata"))
return 0;
/* 提取所有的输入模块。 */
while (pid->dwRVAModuleName)
{
/* 为字符串的绝对偏移量分配缓冲区。 */
pModule[nCnt] = (char *)(pData +
(pid->dwRVAModuleName-idsh.VirtualAddress));
nSize += strlen (pModule[nCnt]) + 1;
/* 增量到下一个输入目录项。*/
pid++;
nCnt++;
}
/* 复制所有字符串到堆内存的一个块当中。 */
*pszModules = (char *)HeapAlloc (hHeap, HEAP_ZERO_MEMORY, nSize);
psz = *pszModules;
for (i=0; i<nCnt; i++)
{
strcpy (psz, pModule[i]);
psz += strlen (psz) + 1;
}
return nCnt;
}
int WINAPI GetImportFunctionNamesByModule (
LPVOID lpFile,
HANDLE hHeap,
char *pszModule,
char **pszFunctions)
{
PIMAGE_IMPORT_MODULE_DIRECTORY pid;
IMAGE_SECTION_HEADER idsh;
DWORD dwBase;
int nCnt = 0, nSize = 0;
DWORD dwFunction;
char *psz;
/* 定位".idata"节的节头。 */
if (!GetSectionHdrByName (lpFile, &idsh, ".idata"))
return 0;
pid = (PIMAGE_IMPORT_MODULE_DIRECTORY)ImageDirectoryOffset
(lpFile, IMAGE_DIRECTORY_ENTRY_IMPORT,NULL);
dwBase = (DWORD)pid;
/* 找出模块的pid。 */
while (pid->dwRVAModuleName &&
strcmp (pszModule,
(char *)(pid->dwRVAModuleName+dwBase)))
pid++;
/* 如果找不到模块则退出。 */
if (!pid->dwRVAModuleName)
return 0;
/* 计算函数名的数量以及字符串的长度。 */
dwFunction = pid->dwRVAFunctionNameList;
while (dwFunction &&
*(DWORD *)(dwFunction + dwBase) &&
*(char *)((*(DWORD *)(dwFunction + dwBase)) +
dwBase+2))
{
nSize += strlen ((char *)((*(DWORD *)(dwFunction +
dwBase)) + dwBase+2)) + 1;
dwFunction += 4;
nCnt++;
}
/* 为函数名在堆中分配内存。 */
*pszFunctions = (char *)HeapAlloc (hHeap, HEAP_ZERO_MEMORY, nSize);
psz = *pszFunctions;
/* 复制函数名到内存指针。 */
dwFunction = pid->dwRVAFunctionNameList;
while (dwFunction &&
*(DWORD *)(dwFunction + dwBase) &&
*((char *)((*(DWORD *)(dwFunction + dwBase)) +
dwBase+2)))
{
strcpy (psz, (char *)((*(DWORD *)(dwFunction + dwBase)) +
dwBase+2));
psz += strlen((char *)((*(DWORD *)(dwFunction + dwBase))+
dwBase+2)) + 1;
dwFunction += 4;
}
return nCnt;
}
|
能力值:
( LV12,RANK:210 )
|
-
-
7 楼
最起码, 你重定位没处理, tls没处理...
关于GetModuleHandleA, 需要在peb中的modulelist增加一个连,
最后, 调用dll某个函数前, 一定要正确的调用一次dll的entrypoint, 也只需调用一次, 同时检测下enterypoint在调用dllmain的时候,参数是否正常.
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
我调用的是DLL。所以有重定位表,这位高手下面说的话,可以解释一下吗?如何操作也请一并告知。谢谢!
最初由 jjnet 发布 最起码, 你重定位没处理, tls没处理... 关于GetModuleHandleA, 需要在peb中的modulelist增加一个连, 最后, 调用dll某个函数前, 一定要正确的调用一次dll的entrypoint, 也只需调用一次, 同时检测下enterypoint在调用dllmain的时候,参数是否正常.
|