/* * crt0pe.s Startup file for PE executable, contents last part of PE * header, because it must be linked by first. Also it contents * common "OptFunc" function. For each API function, OptFunc is * called the first time , that option pointers to DLL entry and * redirect the call. * * Author: Max Feoktistov * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * Compile * command: as crt0pe.s -o crt0pe.o */ ;//as crt0pe.s -o crt0pe.o //.text .section .header ;//Part of PE header. ImageBase: ImportRva: ;// Import Directory Entry .long KernelTbl-ImageBase+0x1000,0,0xFFFFFFFF ;//Import LookUp,Time/Date Stamp,Forward Chain .long sKernel32-ImageBase+0x1000,KernelDTA-ImageBase+0x1000 ;//Name RVA,Addres Table RVA ;// Import Directory Entry .long UserTbl-ImageBase+0x1000,0,0xFFFFFFFF ;//Import LookUp,Time/Date Stamp,Forward Chain .long sUser32-ImageBase+0x1000,UserDTA-ImageBase+0x1000 ;//Name RVA,Addres Table RVA .long 0,0,0,0,0,0,0,0,0 //EndImport: //-------------------- KernelTbl: xExitProcess: .long sExitProcess-ImageBase+0x1000 xGetModuleHandleA: .long sGetModuleHandleA-ImageBase+0x1000 xGetProcAddress: .long sGetProcAddress -ImageBase+0x1000 xLoadLibraryA: .long sLoadLibraryA -ImageBase+0x1000 .long 0 .long 0 .long 0 UserTbl: xMessageBoxA: .long sMessageBoxA -ImageBase+0x1000 .long 0 .long 0 .long 0 sKernel32: .ascii "KERNEL32.DLL\0" sUser32: .ascii "USER32.DLL\0" .long 0,0 sExitProcess: .word 0x7 .asciz "ExitProcess" .align 1,0 sGetModuleHandleA: .word 0x7fff .asciz "GetModuleHandleA" .align 1,0 sGetProcAddress: .word 0x17 .asciz "GetProcAddress" .align 1,0 sLoadLibraryA: .word 0x1C .asciz "LoadLibraryA" .align 4,0 .long 0,0,0 sMessageBoxA: .word 0x9 .asciz "MessageBoxA" .align 4,0 //KernelTbl: KernelDTA: _PExitProcess: ExitProcess: .long sExitProcess -ImageBase+0x1000 _PGetModuleHandleA: GetModuleHandleA: .long sGetModuleHandleA -ImageBase+0x1000 _PGetProcAddress: GetProcAddress: .long sGetProcAddress -ImageBase+0x1000 _PLoadLibraryA: LoadLibraryA: .long sLoadLibraryA -ImageBase+0x1000 .long 0 .long 0 .long 0 ;//-------------- //UserTbl: UserDTA: _PMessageBoxA: MessageBoxA: .long sMessageBoxA -ImageBase+0x1000 .long 0 .long 0 .long 0 .global _PExitProcess .global _PGetProcAddress .global _PLoadLibraryA .global _PMessageBoxA //;;================================================================= .macro Pub_label lbl .globl \lbl \lbl: .endm .macro Debug lng1,lng2,lng3 pushl \lng1 pushl \lng2 pushl \lng3 call dbg_fnc .endm //;;================================================================= .global PEStart PEStart: movl %esp,_beg_esp ;// ;// Prepare stack to call WinMain ;// movl $first_bss,%edi xorl %eax,%eax movl $_end ,%ecx subl %edi,%ecx cld rep; stosb pushl $1 call _GetCommandLineA pushl %eax pushl $0 pushl $0 call *_PGetModuleHandleA movl %eax,__proc_handle pushl %eax ;// ;// FPU init ;// finit pushl %eax ;// fstcww (%esp); ;//for old BNU fstcw (%esp); fwait orb $0x3f,(%esp); ;// fldcww (%esp); ;//for old BNU fldcw (%esp); popl %eax ;// ;// Constructors calls. ;// mov $djgpp_first_ctor,%esi mov $djgpp_last_ctor, %edi constr_call_loop: cmp %esi,%edi jbe 1f cld lodsl call *%eax jmp constr_call_loop 1: call _WinMain .global __exit,__abort,_abort,_exit,__terminate,___terminate __exit: _exit: __terminate: ___terminate: ;// ;// Destructors calls. ;// mov $djgpp_first_dtor,%esi mov $djgpp_last_dtor ,%edi destr_call_loop: cmp %esi,%edi jae 2f cld lodsl call *%eax jmp destr_call_loop 2: __abort: _abort: pushl $0 call *ExitProcess movl _beg_esp,%esp ret _beg_esp: .long 0x40FFFF .global __proc_handle __proc_handle: .long 0 ;//=========================================== MsgNoDLL: .asciz "**Error. Can't load dll library" MsgNoEntry: .asciz "**Error. Can't find function in dll library" .global _OptFunc _OptFunc: movl (%edx),%eax orl %eax,%eax jnz gf1 pushl %edx addl $4,%edx pushl %edx call *_PGetModuleHandleA popl %edx orl %eax,%eax jnz gf2 pushl %edx addl $4,%edx pushl %edx call *_PLoadLibraryA popl %edx orl %eax,%eax jnz gf2 pushl $0 addl $4,%edx pushl %edx pushl $MsgNoDLL pushl $0 call *_PMessageBoxA jmp _abort gf2: movl %eax,(%edx) gf1: movl %eax,%edx movl (%esp),%eax cmpw $0,2(%eax) jne 5f movl (%eax),%eax 5: pushl %eax pushl %edx call *_PGetProcAddress popl %ecx orl %eax,%eax jz _NoService movl %eax,%edx subl %ecx,%eax movl %eax,-4(%ecx) movb $0xE9,-5(%ecx) // jmp %edx ;// for old BNU jmp *%edx _NoService: pushl $0 pushl %ecx pushl $MsgNoEntry pushl $0 call *_PMessageBoxA jmp _abort ;//===========================================