代码:
#include <stdio.h>
#include <windows.h>
DWORD RVAToOffset(LPVOID lpBase,DWORD VirtualAddress)
{
IMAGE_DOS_HEADER *dosHeader;
IMAGE_NT_HEADERS *ntHeader;
IMAGE_SECTION_HEADER *sectionHeader;
int NumOfSections;
dosHeader=(IMAGE_DOS_HEADER*)lpBase;
ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpBase+dosHeader->e_lfanew);
NumOfSections=ntHeader->FileHeader.NumberOfSections;
for (int i=0;i<NumOfSections;i++)
{
sectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpBase+dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS))+i;
if(VirtualAddress>sectionHeader->VirtualAddress&&VirtualAddress<sectionHeader->VirtualAddress+sectionHeader->SizeOfRawData)
{
DWORD AposRAV=VirtualAddress-sectionHeader->VirtualAddress;
DWORD Offset=sectionHeader->PointerToRawData+AposRAV;
return Offset;
}
}
return 0;
}
int sectionNum(LPVOID lpBase,DWORD VirtualAddress)
{
IMAGE_DOS_HEADER *dosHeader;
IMAGE_NT_HEADERS *ntHeader;
IMAGE_SECTION_HEADER *sectionHeader;
int NumOfSections;
dosHeader=(IMAGE_DOS_HEADER*)lpBase;
ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpBase+dosHeader->e_lfanew);
NumOfSections=ntHeader->FileHeader.NumberOfSections;
for (int i=0;i<NumOfSections;i++)
{
sectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpBase+dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS))+i;
if(VirtualAddress>sectionHeader->VirtualAddress&&VirtualAddress<sectionHeader->VirtualAddress+sectionHeader->SizeOfRawData)
{
return i;
}
}
return -1;
}
int main(int argc, char* argv[])
{
HANDLE hFile=CreateFile(argv[1],GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
printf("CreateFile Failed/n");
return 0;
}
HANDLE hMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE,NULL,NULL,NULL);
if(hMap==INVALID_HANDLE_VALUE)
{
printf("CreateFileMapping Failed/n");
return 0;
}
LPVOID lpBase=MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);
if(lpBase==NULL)
{
printf("MapViewOfFile Failed/n");
return 0;
}
IMAGE_DOS_HEADER *dosHeader;
IMAGE_NT_HEADERS *ntHeader;
dosHeader=(IMAGE_DOS_HEADER*)lpBase;
if (dosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
printf("This is not a windows file/n");
return 0;
}
ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpBase+dosHeader->e_lfanew);
if(ntHeader->Signature!=IMAGE_NT_SIGNATURE)
{
printf("This is not a win32 file/n");
return 0;
}
int numOfSections=ntHeader->FileHeader.NumberOfSections;
int ncout=sectionNum(lpBase,ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
if(ncout==-1)
{
printf("get section failed/n");
return 0;
}
IMAGE_SECTION_HEADER *sectionHeader;
sectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpBase+dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS))+ncout;
int nullsize=sectionHeader->SizeOfRawData-sectionHeader->Misc.VirtualSize;
printf("%d/n",nullsize);
if(numOfSections*20+20*3+8+8>nullsize)
{
printf("file space is not enough/n");
return 0;
}
IMAGE_IMPORT_DESCRIPTOR *newImport;
newImport=(IMAGE_IMPORT_DESCRIPTOR *)((BYTE*)lpBase+sectionHeader->PointerToRawData+sectionHeader->Misc.VirtualSize);
printf("%x/n",sectionHeader->PointerToRawData+sectionHeader->Misc.VirtualSize);
printf("%d/n",sizeof(IMAGE_IMPORT_DESCRIPTOR));
IMAGE_IMPORT_DESCRIPTOR *ImportDec=(IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)lpBase+RVAToOffset(lpBase,ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
int i=0;
while(ImportDec->FirstThunk)
{
*newImport=*ImportDec;
i=i+1;
ImportDec++;
newImport++;
}
IMAGE_IMPORT_DESCRIPTOR myImport;
char *name="my.dll";
myImport.FirstThunk=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->VirtualAddress+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2)+20);
myImport.TimeDateStamp=0;
myImport.ForwarderChain=0;
myImport.OriginalFirstThunk=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->PointerToRawData+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2)+20);
myImport.Name=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->VirtualAddress+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2));
*newImport=myImport;
newImport++;
memset(newImport,0,sizeof(IMAGE_IMPORT_DESCRIPTOR));
newImport++;
memcpy((char*)newImport,name,strlen(name)+1);
DWORD newThunk;
newThunk=(DWORD)newImport+20;
*(DWORD*)newThunk=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->VirtualAddress+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2)+20+8);
memset((void*)(newThunk+4),0,4);
newThunk=newThunk+8;
WORD hint=0x00;
*(WORD*)newThunk=hint;
newThunk=newThunk+sizeof(WORD);
char *funname="MyFun";
memcpy((char*)newThunk,funname,strlen(funname)+2);
ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress=sectionHeader->Misc.VirtualSize+sectionHeader->VirtualAddress;
FlushViewOfFile(lpBase,0);
UnmapViewOfFile(lpBase);
CloseHandle(hMap);
CloseHandle(hFile);
return 0;
}
#include <stdio.h>
#include <windows.h>
DWORD RVAToOffset(LPVOID lpBase,DWORD VirtualAddress)
{
IMAGE_DOS_HEADER *dosHeader;
IMAGE_NT_HEADERS *ntHeader;
IMAGE_SECTION_HEADER *sectionHeader;
int NumOfSections;
dosHeader=(IMAGE_DOS_HEADER*)lpBase;
ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpBase+dosHeader->e_lfanew);
NumOfSections=ntHeader->FileHeader.NumberOfSections;
for (int i=0;i<NumOfSections;i++)
{
sectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpBase+dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS))+i;
if(VirtualAddress>sectionHeader->VirtualAddress&&VirtualAddress<sectionHeader->VirtualAddress+sectionHeader->SizeOfRawData)
{
DWORD AposRAV=VirtualAddress-sectionHeader->VirtualAddress;
DWORD Offset=sectionHeader->PointerToRawData+AposRAV;
return Offset;
}
}
return 0;
}
int sectionNum(LPVOID lpBase,DWORD VirtualAddress)
{
IMAGE_DOS_HEADER *dosHeader;
IMAGE_NT_HEADERS *ntHeader;
IMAGE_SECTION_HEADER *sectionHeader;
int NumOfSections;
dosHeader=(IMAGE_DOS_HEADER*)lpBase;
ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpBase+dosHeader->e_lfanew);
NumOfSections=ntHeader->FileHeader.NumberOfSections;
for (int i=0;i<NumOfSections;i++)
{
sectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpBase+dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS))+i;
if(VirtualAddress>sectionHeader->VirtualAddress&&VirtualAddress<sectionHeader->VirtualAddress+sectionHeader->SizeOfRawData)
{
return i;
}
}
return -1;
}
int main(int argc, char* argv[])
{
HANDLE hFile=CreateFile(argv[1],GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
printf("CreateFile Failed/n");
return 0;
}
HANDLE hMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE,NULL,NULL,NULL);
if(hMap==INVALID_HANDLE_VALUE)
{
printf("CreateFileMapping Failed/n");
return 0;
}
LPVOID lpBase=MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);
if(lpBase==NULL)
{
printf("MapViewOfFile Failed/n");
return 0;
}
IMAGE_DOS_HEADER *dosHeader;
IMAGE_NT_HEADERS *ntHeader;
dosHeader=(IMAGE_DOS_HEADER*)lpBase;
if (dosHeader->e_magic!=IMAGE_DOS_SIGNATURE)
{
printf("This is not a windows file/n");
return 0;
}
ntHeader=(IMAGE_NT_HEADERS*)((BYTE*)lpBase+dosHeader->e_lfanew);
if(ntHeader->Signature!=IMAGE_NT_SIGNATURE)
{
printf("This is not a win32 file/n");
return 0;
}
int numOfSections=ntHeader->FileHeader.NumberOfSections;
int ncout=sectionNum(lpBase,ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
if(ncout==-1)
{
printf("get section failed/n");
return 0;
}
IMAGE_SECTION_HEADER *sectionHeader;
sectionHeader=(IMAGE_SECTION_HEADER*)((BYTE*)lpBase+dosHeader->e_lfanew+sizeof(IMAGE_NT_HEADERS))+ncout;
int nullsize=sectionHeader->SizeOfRawData-sectionHeader->Misc.VirtualSize;
printf("%d/n",nullsize);
if(numOfSections*20+20*3+8+8>nullsize)
{
printf("file space is not enough/n");
return 0;
}
IMAGE_IMPORT_DESCRIPTOR *newImport;
newImport=(IMAGE_IMPORT_DESCRIPTOR *)((BYTE*)lpBase+sectionHeader->PointerToRawData+sectionHeader->Misc.VirtualSize);
printf("%x/n",sectionHeader->PointerToRawData+sectionHeader->Misc.VirtualSize);
printf("%d/n",sizeof(IMAGE_IMPORT_DESCRIPTOR));
IMAGE_IMPORT_DESCRIPTOR *ImportDec=(IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)lpBase+RVAToOffset(lpBase,ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
int i=0;
while(ImportDec->FirstThunk)
{
*newImport=*ImportDec;
i=i+1;
ImportDec++;
newImport++;
}
IMAGE_IMPORT_DESCRIPTOR myImport;
char *name="my.dll";
myImport.FirstThunk=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->VirtualAddress+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2)+20);
myImport.TimeDateStamp=0;
myImport.ForwarderChain=0;
myImport.OriginalFirstThunk=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->PointerToRawData+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2)+20);
myImport.Name=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->VirtualAddress+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2));
*newImport=myImport;
newImport++;
memset(newImport,0,sizeof(IMAGE_IMPORT_DESCRIPTOR));
newImport++;
memcpy((char*)newImport,name,strlen(name)+1);
DWORD newThunk;
newThunk=(DWORD)newImport+20;
*(DWORD*)newThunk=(DWORD)(sectionHeader->Misc.VirtualSize+sectionHeader->VirtualAddress+sizeof(IMAGE_IMPORT_DESCRIPTOR)*(i+2)+20+8);
memset((void*)(newThunk+4),0,4);
newThunk=newThunk+8;
WORD hint=0x00;
*(WORD*)newThunk=hint;
newThunk=newThunk+sizeof(WORD);
char *funname="MyFun";
memcpy((char*)newThunk,funname,strlen(funname)+2);
ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress=sectionHeader->Misc.VirtualSize+sectionHeader->VirtualAddress;
FlushViewOfFile(lpBase,0);
UnmapViewOfFile(lpBase);
CloseHandle(hMap);
CloseHandle(hFile);
return 0;
}