69,382
社区成员
发帖
与我相关
我的任务
分享
#include "lyPELoader.h"
#define SIZE_OF_NT_SIGNATURE sizeof(DWORD)
HINSTANCE lyLoadLibraryA(char* filename){
FILE* fp;
char* dllbuff = NULL;
struct stat stbuf = {0};
unsigned int fd;
HINSTANCE hdll;
fp = fopen(filename,"rb+");
if(fp == NULL){
lyDbgPrintf("读取文件%s失败\n",filename);
return NULL;
}
fd = _fileno(fp);
fstat(fd,&stbuf);
if(stbuf.st_size > 1024*1024*100){
lyDbgPrintf("文件大小异常%d\n",(int)stbuf.st_size);
return NULL;
}
dllbuff = (char*)malloc(stbuf.st_size);
fread(dllbuff,1,stbuf.st_size,fp);
hdll = lyLoadLibraryFromMemory(dllbuff,stbuf.st_size);
free(dllbuff);
fclose(fp);
return hdll;
}
HINSTANCE lyLoadLibraryFromMemory(char* dllbuff,_off_t buffsize){
PIMAGE_DOS_HEADER doshdr = (PIMAGE_DOS_HEADER)dllbuff;
PIMAGE_NT_HEADERS nthdr;
PIMAGE_FILE_HEADER filehdr;
PIMAGE_OPTIONAL_HEADER opthdr;
PIMAGE_SECTION_HEADER sechdr;
int imagesize;
char *imagebase;
int sectioncount;
int headsize;
int index;
int falignchk;
int salignchk;
/*初始化文件头*/
nthdr = (PIMAGE_NT_HEADERS)((char*)doshdr + doshdr->e_lfanew);
filehdr = (PIMAGE_FILE_HEADER)((char*)nthdr + SIZE_OF_NT_SIGNATURE);
opthdr = (PIMAGE_OPTIONAL_HEADER)((char*)filehdr + sizeof(IMAGE_FILE_HEADER));
sechdr = (PIMAGE_SECTION_HEADER)((char*)opthdr + sizeof (IMAGE_OPTIONAL_HEADER));
/*检查有效性*/
if(IMAGE_DOS_SIGNATURE != *(unsigned short*)doshdr){
lyDbgPrintf("DOS标志错误\n");
return NULL;
}
/*初始化变量*/
imagesize = nthdr->OptionalHeader.SizeOfImage;
imagebase = VirtualAlloc((char*)nthdr->OptionalHeader.ImageBase,imagesize,MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
sectioncount = nthdr->FileHeader.NumberOfSections;
headsize = (int)sechdr + sizeof(PIMAGE_SECTION_HEADER) - (int)doshdr;
falignchk = nthdr->OptionalHeader.FileAlignment - 1;
salignchk = nthdr->OptionalHeader.SectionAlignment - 1;
if(NULL == imagebase){
imagebase = VirtualAlloc(NULL,imagesize,MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if(NULL == imagebase){
lyDbgPrintf("申请内存失败\n");
return NULL;
}
}
/*加载PE头*/
memcpy(imagebase,doshdr,headsize);
/*加载各段*/
for(index = 0; index < sectioncount; index++, sechdr++){
if((sechdr->VirtualAddress & salignchk) || (sechdr->SizeOfRawData & falignchk)){
lyDbgPrintf("段检查错误\n");
free(imagebase);
return NULL;
}
memcpy(imagebase + sechdr->VirtualAddress, (char*)doshdr + sechdr->PointerToRawData, sechdr->SizeOfRawData);
}
/*加载导入表*/
if(nthdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size > 0){
PIMAGE_IMPORT_DESCRIPTOR impdsc = (IMAGE_IMPORT_DESCRIPTOR *)(imagebase + nthdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
/*加载各导入表*/
for(;impdsc->Name != 0;impdsc++){
PIMAGE_THUNK_DATA thunk = (PIMAGE_THUNK_DATA)(imagebase + impdsc->FirstThunk);
char* filename = imagebase + impdsc->Name;
HINSTANCE expdll;
if(strnicmp(filename,"msvcr",5) == 0){
filename = "C:\\WINDOWS\\WinSxS\\x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.30729.1_x-ww_6f74963e\\msvcr90.dll";
printf("修正%s为%s\n",imagebase + impdsc->Name,filename);
}
expdll = LoadLibrary(filename);
/*expdll = lyLoadLibraryA(filename);*/
/*HINSTANCE expdll = lyLoadLibraryA(imagebase + impdsc->Name);*/
if(expdll == NULL){
lyDbgPrintf("依赖项%s加载失败\n",(char*)imagebase + impdsc->Name);
free(imagebase);
return NULL;
}
lyDbgPrintf("依赖项%s加载成功\n",(char*)imagebase + impdsc->Name);
/*加载一个导入表中的各函数*/
for(;thunk->u1.Ordinal != 0; thunk++){
FARPROC proc;
if(thunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32){
/*proc = GetProcAddress(expdll, (char*)(thunk->u1.Ordinal & 0x0000ffff));*/
proc = lyGetProcAddressA(expdll, (char*)(thunk->u1.Ordinal & 0x0000ffff));
}else{
/*proc = GetProcAddress(expdll, (char*)((IMAGE_IMPORT_BY_NAME *)(imagebase + thunk->u1.Ordinal))->Name);*/
proc = lyGetProcAddressA(expdll, (char*)((IMAGE_IMPORT_BY_NAME *)(imagebase + thunk->u1.Ordinal))->Name);
}
if(proc == NULL){
lyDbgPrintf("函数导入错误\n");
free(imagebase);
return NULL;
}
thunk->u1.Ordinal = (int)proc;
}
/*FreeLibrary(expdll); 争议*/
}
}
/*加载重定位表*/
if(nthdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size > 0){
PIMAGE_BASE_RELOCATION rel = (PIMAGE_BASE_RELOCATION)(imagebase + nthdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
int reldiff = (int)imagebase - nthdr->OptionalHeader.ImageBase;
/*加载各重定位表*/
for(;rel->VirtualAddress != 0;){
char* relpagebase = imagebase + rel->VirtualAddress;
int relitemcount = (rel->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) >> 1;
short* relitem = (short*)(rel + sizeof(IMAGE_BASE_RELOCATION));
/*加载一个重定位表中的各项*/
for(index = 0;index < relitemcount;index++){
int offset = relitem[index] & 0xfff;
int type = relitem[index] >> 12;
switch(type){
case IMAGE_REL_BASED_ABSOLUTE:
break;
case IMAGE_REL_BASED_HIGH:
break;
case IMAGE_REL_BASED_LOW:
break;
case IMAGE_REL_BASED_HIGHLOW:
*(int *)(relpagebase + offset) += reldiff;
break;
case IMAGE_REL_BASED_HIGHADJ:
break;
case IMAGE_REL_BASED_MIPS_JMPADDR:
break;
}
}
rel = (PIMAGE_BASE_RELOCATION)(relitem + relitemcount);
}
}
/*调用DLL入口函数*/{
typedef BOOL WINAPI (*DllMain)(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved);
DllMain mainproc = (DllMain)lyGetProcAddressA((HINSTANCE)imagebase,"DllMain");
if(mainproc){
if(mainproc((HINSTANCE)imagebase,DLL_PROCESS_ATTACH,0) == FALSE){
VirtualFree((char*)imagebase,0,MEM_RELEASE);
}
}
}
return (HINSTANCE)imagebase;
}
void lyFreeLibrary(HINSTANCE module){
typedef BOOL WINAPI (*DllMain)(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved);
DllMain mainproc = (DllMain)lyGetProcAddressA(module,"DllMain");
if(mainproc){
mainproc(module,DLL_PROCESS_DETACH,0);
}
VirtualFree((char*)module,0,MEM_RELEASE);
}
FARPROC lyGetProcAddressA(HINSTANCE module,char* procname){
PIMAGE_DOS_HEADER doshdr = (PIMAGE_DOS_HEADER)module;
PIMAGE_NT_HEADERS nthdr;
PIMAGE_FILE_HEADER filehdr;
PIMAGE_OPTIONAL_HEADER opthdr;
PIMAGE_SECTION_HEADER sechdr;
PIMAGE_SECTION_HEADER edatasec;
PIMAGE_EXPORT_DIRECTORY expdir;
char *imagebase = (char*)module;
int sectioncount;
int index;
int procnamelength = strlen(procname);
/*初始化文件头*/
nthdr = (PIMAGE_NT_HEADERS)((char*)doshdr + doshdr->e_lfanew);
filehdr = (PIMAGE_FILE_HEADER)((char*)nthdr + SIZE_OF_NT_SIGNATURE);
opthdr = (PIMAGE_OPTIONAL_HEADER)((char*)filehdr + sizeof(IMAGE_FILE_HEADER));
sechdr = (PIMAGE_SECTION_HEADER)((char*)opthdr + sizeof (IMAGE_OPTIONAL_HEADER));
/*检查有效性*/
if(IMAGE_DOS_SIGNATURE != *(unsigned short*)doshdr){
lyDbgPrintf("DOS标志错误\n");
return NULL;
}
/*初始化变量*/
sectioncount = nthdr->FileHeader.NumberOfSections;
procnamelength = strlen(procname);
for (index=0,edatasec = sechdr;index < sectioncount;index++,edatasec++){
if (!strcmp ((char*)sechdr->Name, ".edata")){
break;
}
}
expdir = (PIMAGE_EXPORT_DIRECTORY)(imagebase + nthdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
for(index=0;index < expdir->NumberOfFunctions;index++){
int function = *(int*)(imagebase + expdir->AddressOfFunctions + index*sizeof(void*));
char* name = imagebase + (int)*(char**)(imagebase + expdir->AddressOfNames + index*sizeof(void*));
/*short ordinal = *(short*)(imagebase + expdir->AddressOfNameOrdinals + index*sizeof(void*)); 函数序号,因为不需要所以省略了*/
if(strnicmp(name,procname,procnamelength) == 0){
return (FARPROC)(function + (int)imagebase);
}
}
lyDbgPrintf("未找到符号\n");
return NULL;
}
什么系统?
看你的程序是否具有相应的权限?