首页
社区
课程
招聘
[原创]发一个11年前写的纯汇编X64 PELoader
2023-5-23 12:36 13048

[原创]发一个11年前写的纯汇编X64 PELoader

2023-5-23 12:36
13048


可以转成shellcode,无文件注入dll,编写壳程序,外挂等。。。


;--- Win64 "hello world" GUI application.
;--- assemble: JWasm -win64 Win64_1.asm
;--- to link, use MS link, Polink or JWlink:
;--- MS link: link /subsystem:windows /entry:main Win64_1.obj
;--- Polink:  polink /subsystem:windows /entry:main Win64_1.obj
;--- JWlink:  je

option casemap:none
option win64:6

;    OPTION WIN64: switches 
;
;accepted values for switches are:
;
;    Store Register Arguments [ bit 0 ]: 
;    - 0: the "home locations" (also sometimes called "shadow space") of the first 4 register parameters are uninitialized. This is the default setting. 
;    - 1: register contents of the PROC's first 4 parameters (RCX, RDX, R8 and R9 ) will be copied to the "home locations" within a PROC's prologue. 
;
;    INVOKE Stack Space Reservation [bit 1]: 
;    - 0: for each INVOKE the stack is adjusted to reserve space for the parameters required for the call. After the call, the space is released again. This is the default setting. 
;    - 1: the maximum stack space required by all INVOKEs inside a procedure is computed by the assembler and reserved once on the procedure's entry. It's released when the procedure is exited. If INVOKEs are to be used outside of procedures, the stack space has to be reserved manually!
;    Note: an assembly time variable, @ReservedStack, is created internally when this option is set. It will reflect the value computed by the assembler. It should also be mentioned that when this option is on, and a procedure contains no INVOKEs at all, then nevertheless the minimal amount of 4*8 bytes is reserved on the stack.
;    Warning: You should have understood exactly what this option does BEFORE you're using it. Using PUSH/POP instruction pairs to "save" values across an INVOKE is VERBOTEN if this option is on. 
;
;    16-byte Alignment for Local Stack Variables [bit 2]: 
;    0: standard 8-byte alignment for local variables. 
;    1: 16-byte alignment for local variables. This setting is useful if you want to load or store XMM registers with instructions that expect aligned memory references ( i.e. MOVAPS ). Note that variables with size < 16 are not affected. 
    
    
includelib kernel32.lib

externdef MessageBoxA : near
externdef ExitProcess : near

IMAGE_DIRECTORY_ENTRY_EXPORT                    equ  0
IMAGE_DIRECTORY_ENTRY_IMPORT                    equ  1
IMAGE_DIRECTORY_ENTRY_RESOURCE                equ  2
IMAGE_DIRECTORY_ENTRY_EXCEPTION               equ  3
IMAGE_DIRECTORY_ENTRY_SECURITY                  equ  4
IMAGE_DIRECTORY_ENTRY_BASERELOC                 equ  5
IMAGE_DIRECTORY_ENTRY_DEBUG                     equ  6
IMAGE_DIRECTORY_ENTRY_COPYRIGHT             equ  7
IMAGE_DIRECTORY_ENTRY_GLOBALPTR             equ  8
IMAGE_DIRECTORY_ENTRY_TLS                           equ  9
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG           equ 10
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT          equ 11
IMAGE_DIRECTORY_ENTRY_IAT                           equ 12
IMAGE_NUMBEROF_DIRECTORY_ENTRIES            equ 16

GENERIC_READ                         equ 80000000h
GENERIC_WRITE                        equ 40000000h
GENERIC_EXECUTE                      equ 20000000h
GENERIC_ALL                          equ 10000000h
FILE_SHARE_WRITE                     equ 2h
NULL EQU 0
OPEN_EXISTING                        equ 3
FILE_ATTRIBUTE_NORMAL                equ 80h
MEM_COMMIT                equ 1000h
MEM_RESERVE               equ 2000h
PAGE_EXECUTE_READWRITE    equ 40h
IMAGE_SIZEOF_SHORT_NAME equ 8

IMAGE_BASE_RELOCATION STRUCT
    VirtualAddress dd   ?
    SizeOfBlock dd      ?
IMAGE_BASE_RELOCATION ENDS

IMAGE_SECTION_HEADER STRUCT
    Name1 BYTE IMAGE_SIZEOF_SHORT_NAME dup(?)
    union Misc
        PhysicalAddress DWORD  ?
        VirtualSize DWORD      ?
    ends
    VirtualAddress DWORD       ?
    SizeOfRawData DWORD        ?
    PointerToRawData DWORD     ?
    PointerToRelocations DWORD ?
    PointerToLinenumbers DWORD ?
    NumberOfRelocations WORD  ?
    NumberOfLinenumbers WORD  ?
    Characteristics DWORD      ?
IMAGE_SECTION_HEADER ENDS

IMAGE_IMPORT_DESCRIPTOR STRUCT
    union
        Characteristics DWORD      ?
        OriginalFirstThunk DWORD   ?
     ends
    TimeDateStamp DWORD    ?
    ForwarderChain DWORD   ?
    Name1 DWORD            ?
    FirstThunk DWORD       ?
IMAGE_IMPORT_DESCRIPTOR ENDS

IMAGE_DATA_DIRECTORY STRUCT
  VirtualAddress    DWORD      ?
  isize             DWORD      ?
IMAGE_DATA_DIRECTORY ENDS

IMAGE_EXPORT_DIRECTORY STRUCT
  Characteristics           DWORD      ?
  TimeDateStamp             DWORD      ?
  MajorVersion              WORD       ?
  MinorVersion              WORD       ?
  nName                     DWORD      ?
  nBase                     DWORD      ?
  NumberOfFunctions         DWORD      ?
  NumberOfNames             DWORD      ?
  AddressOfFunctions        DWORD      ?
  AddressOfNames            DWORD      ?
  AddressOfNameOrdinals     DWORD      ?
IMAGE_EXPORT_DIRECTORY ENDS

IMAGE_OPTIONAL_HEADER64 STRUCT
  Magic                         WORD       ?
  MajorLinkerVersion            BYTE       ?
  MinorLinkerVersion            BYTE       ?
  SizeOfCode                    DWORD      ?
  SizeOfInitializedData         DWORD      ?
  SizeOfUninitializedData       DWORD      ?
  AddressOfEntryPoint           DWORD      ?
  BaseOfCode                    DWORD      ?
  ImageBase                     QWORD      ?
  SectionAlignment              DWORD      ?
  FileAlignment                 DWORD      ?
  MajorOperatingSystemVersion   WORD       ?
  MinorOperatingSystemVersion   WORD       ?
  MajorImageVersion             WORD       ?
  MinorImageVersion             WORD       ?
  MajorSubsystemVersion         WORD       ?
  MinorSubsystemVersion         WORD       ?
  Win32VersionValue             DWORD      ?
  SizeOfImage                   DWORD      ?
  SizeOfHeaders                 DWORD      ?
  CheckSum                      DWORD      ?
  Subsystem                     WORD       ?
  DllCharacteristics            WORD       ?
  SizeOfStackReserve            QWORD      ?
  SizeOfStackCommit             QWORD      ?
  SizeOfHeapReserve             QWORD      ?
  SizeOfHeapCommit              QWORD      ?
  LoaderFlags                   DWORD      ?
  NumberOfRvaAndSizes           DWORD      ?
  DataDirectory                 IMAGE_DATA_DIRECTORY IMAGE_NUMBEROF_DIRECTORY_ENTRIES dup(<>)
IMAGE_OPTIONAL_HEADER64 ENDS

IMAGE_FILE_HEADER STRUCT
  Machine               WORD    ?
  NumberOfSections      WORD    ?
  TimeDateStamp         DWORD   ?
  PointerToSymbolTable  DWORD   ?
  NumberOfSymbols       DWORD   ?
  SizeOfOptionalHeader  WORD    ?
  Characteristics       WORD    ?
IMAGE_FILE_HEADER ENDS

IMAGE_NT_HEADERS64 STRUCT
  Signature         DWORD                   ?
  FileHeader        IMAGE_FILE_HEADER       <>
  OptionalHeader    IMAGE_OPTIONAL_HEADER64 <>
IMAGE_NT_HEADERS64 ENDS
CreateFileA proto :qword, :qword, :qword, :qword, :qword, :qword, :qword
GetFileSize proto :qword, :qword
VirtualAlloc proto :qword, :qword, :qword, :qword
_lread proto :qword, :qword, :qword
GetProcAddressByName proto :QWORD, :QWORD
GetKernel32Base proto
 .data
aLoadLibraryA db 'LoadLibraryA',0h
filepath db 'r77-x64.dll',0

.code
LoadDll proc  uses r12 r13 r14 r15 rbx rsi rdi    pDllBaseAddressRaw:QWORD 
        LOCAL kernel32Base:QWORD
        LOCAL pLoadLibraryA:QWORD
        LOCAL pGetProcAddress:QWORD
        LOCAL pVirtualAlloc:QWORD
        LOCAL pCloseHandle:QWORD
        LOCAL pDllMemory:QWORD
        LOCAL pCreateFileA:QWORD
        LOCAL pGetFileSize:QWORD
        LOCAL p_lread:QWORD
        LOCAL hFile:QWORD
        LOCAL dwFileSize:qword
        LOCAL pDllRaw:qword
        LOCAL pImageBase:QWORD

        mov r12,rcx

        invoke GetKernel32Base
        mov kernel32Base,rax

    
        mov     rcx,kernel32Base
        call @F
        db "LoadLibraryA",0
        @@:pop rdx
        invoke GetProcAddressByName, rcx,rdx
        mov pLoadLibraryA,rax
        
        mov     rcx,kernel32Base
        call @F
        db "GetProcAddress",0
        @@:pop rdx
        invoke GetProcAddressByName, rcx,rdx
        mov pGetProcAddress,rax
        
        mov     rcx,kernel32Base
        call @F
        db "VirtualAlloc",0
        @@:pop rdx
        invoke GetProcAddressByName, rcx,rdx
        mov pVirtualAlloc,rax
        
        ;----------------------------------------
        ;调试代码专用
;        mov     rcx,kernel32Base
;        call @F
;        db "CreateFileA",0
;        @@:pop rdx
;        invoke GetProcAddressByName, rcx,rdx
;        mov pCreateFileA,rax
;
;        mov     rcx,kernel32Base
;        call @F
;        db "GetFileSize",0
;        @@:pop rdx
;        invoke GetProcAddressByName, rcx,rdx
;        mov pGetFileSize,rax
;        
;        mov     rcx,kernel32Base
;        call @F
;        db "_lread",0
;        @@:pop rdx
;        invoke GetProcAddressByName, rcx,rdx
;        mov p_lread,rax
;        
;        mov     rcx,kernel32Base
;        call @F
;        db "CloseHandle",0
;        @@:pop rdx
;        invoke GetProcAddressByName, rcx,rdx
;        mov pCloseHandle,rax
        
;       本地调试专用
;        invoke CreateFileA,offset filepath,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
;        mov hFile,rax
;        invoke GetFileSize,hFile,NULL
;        mov dwFileSize,rax
;
;        invoke VirtualAlloc,NULL,RAX,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE
;        mov pDllRaw,rax
;        invoke _lread,hFile,pDllRaw,dwFileSize
         ;----------------------------------------

        ;R12指向DOS头
        ;R13 指向PE头
        ;R14指向新dll DOS头
        ;mov     r12,pDllRaw;R12指向DOS头
        mov    r13d,dword ptr [r12+3ch];获取PE头偏移
        add     r13,r12; R13 指向PE头
        assume r13:ptr IMAGE_NT_HEADERS64
        ;mov r9d,[r13].OptionalHeader.SizeOfImage
        mov rcx,NULL
        mov edx,[r13].OptionalHeader.SizeOfImage
        mov r8,MEM_COMMIT or MEM_RESERVE
        mov r9,PAGE_EXECUTE_READWRITE
        sub rsp,4*8
        call pVirtualAlloc;invoke VirtualAlloc,NULL,r9,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE
        add rsp,4*8
        mov R14,rax;R14指向新dll DOS头
        
        ;复制头
        mov rsi,R12
        mov rdi,R14
        mov rcx,400h
        cld 
        rep movsb 
        
        ;复制节
        mov dx, [r13].FileHeader.SizeOfOptionalHeader;读取可选头大小
        lea rdx,[r13+rdx+5*4+4];计算节表VA偏移
        assume rdx:ptr IMAGE_SECTION_HEADER
        mov cx,word ptr [r13].FileHeader.NumberOfSections; 节数量
        .repeat
                push rcx
                mov esi,dword ptr [rdx].PointerToRawData;获取节文件偏移
                add rsi, r12;
                mov edi,dword ptr [rdx].VirtualAddress
                add rdi,r14
                mov ecx,dword ptr [rdx].SizeOfRawData
                rep movsb
                pop rcx
                add rdx,sizeof IMAGE_SECTION_HEADER
        .untilcxz
        
        ;处理重定位表
        mov r15,[r13].OptionalHeader.ImageBase
        
        mov edx,dword ptr [r13].OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC*8].VirtualAddress
        add rdx, r14;重定位表基础地址
        assume rdx:ptr IMAGE_BASE_RELOCATION
        .while [rdx].VirtualAddress
                mov ecx,dword ptr [rdx].SizeOfBlock
                sub ecx,sizeof IMAGE_BASE_RELOCATION
                shr ecx,1;ecx=本快需要重定位的个数
                
                lea rsi,[rdx+sizeof IMAGE_BASE_RELOCATION];本块第一个重定位数据指针
                lodsw
                .repeat
                        test ax,3000h;IMAGE_REL_BASED_HIGHLOW<<12
                        .if !ZERO?
                                 ;计算需要进行重定位的地址
                    ;重定位数据的低12位再加上本重定位块头的RAV即真正需要重定位的数据的RAV
            
                            and rax,0fffh;小偏移
                            add eax,dword ptr [rdx].VirtualAddress
                            add rax,r14
                            mov rdi,qword ptr [rax]
                            sub rdi,r15
                            add rdi,r14
                            mov qword ptr[rax],rdi
                        .endif
                        lodsw;指向本块下一个重定位指针
                .untilcxz
                mov r11d,dword ptr [rdx].SizeOfBlock;指向下一个重定位块
                add rdx,r11
        .endw
        

        ;处理输入表
        mov ebx,[r13].OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT*8].VirtualAddress
        add rbx,r14 
        assume rbx: ptr IMAGE_IMPORT_DESCRIPTOR;本块IMAGE_IMPORT_DESCRIPTOR
        .while [rbx].FirstThunk
                mov ecx,dword ptr [rbx].Name1;导入表dll名称RVA
                add rcx,r14
                sub rsp,8*4
                call pLoadLibraryA;invoke pLoadLibrary,[ebx].Name1
                add rsp,8*4
                mov r15,rax;  R15导入表dl的基础地址
                
                IMAGE_THUNK_DATA32 STRUCT
                    union u1
                        ForwarderString DWORD  ?
                        Function DWORD         ?
                        Ordinal DWORD          ?
                        AddressOfData DWORD    ?
                    ends
                IMAGE_THUNK_DATA32 ENDS
                
                .if ![rbx].OriginalFirstThunk
                    mov esi,[rbx].FirstThunk
                .else    
                    mov esi,[rbx].OriginalFirstThunk
                .endif
                mov edi,dword ptr [rbx].FirstThunk
                add rdi,r14
                add rsi,r14
                lodsq
                .while  RAX
                        btr eax,31
                        .if CARRY?
                                mov rcx,r15
                                mov rdx,rax
                                sub rsp,4*8
                                call pGetProcAddress;invoke pGetProcAddress,hMoudle,eax
                                add rsp,4*8
                        .else    
                                ;函数以名字导出的代码
                            add rax,r14
                            inc rax
                            inc rax
                            mov rcx,r15
                            mov rdx,rax
                            sub rsp,4*8
                            call pGetProcAddress;invoke pGetProcAddress,hMoudle,eax
                            add rsp,4*8
                        .endif
                        stosq
                        lodsq 
                .endw
                

                add rbx,20;下一块块IMAGE_IMPORT_DESCRIPTOR   
        .endw
        
        ;调用DLLMAIN
        mov eax,dword ptr [r13].OptionalHeader.AddressOfEntryPoint
        add rax,r14
        mov rcx,r14
        mov rdx,1
        mov r8,0
        sub rsp,4*8
        call rax
        add rsp,4*8

        ret
LoadDll endp
GetKernel32Base PROC
       mov      r8,gs:[60h]
       mov      r8,qword ptr [r8+18h]
       mov      r8,qword ptr [r8+30h]
       mov      r8,qword ptr [r8]
       mov      r8,qword ptr [r8]
       mov      rax,qword ptr [r8+10h]
       ret
GetKernel32Base ENDP
GetProcAddressByName PROC hModule:QWORD,lpProcName :QWORD
            ;int 3
            ;mov hModule,rcx
            ;r10 dll基础地址
            LOCAL StrSize:QWORD
            push rsi
            push rdi

                mov    r10,rcx              ;r10 is the module base
                
                ;获取字符串长度
                mov    rdi, rdx
            xor     ecx,ecx
            dec     ecx
            xor    al, al
            cld
            repnz   scasb
            neg     ecx
            dec     ecx
            mov    StrSize, rcx
    
    
        mov    r11d,dword ptr [r10+3ch];获取PE头偏移
                add     r11,r10
                
                assume r11:ptr IMAGE_NT_HEADERS64
        ;直接读的结构体里面的偏移,这个用winDbg看可能比较直观一点
        mov    r11d,dword ptr [r11].OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress ;输出表RVA OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress 
                
                add     r11,r10;输入表地址
                assume r11 :ptr IMAGE_EXPORT_DIRECTORY

        mov     ecx,dword ptr [r11].NumberOfNames;ImageExportDirectory.NumberOfNames
        mov     r8d,dword ptr [r11].AddressOfNames
        add      r8,r10
        dec ecx;函数名个数
        cld
                .repeat
                        push rcx
                        mov esi,dword ptr [r8+rcx*4]
                        add rsi,r10;得到函数名称VA
                        mov rdi, rdx
                        mov rcx, StrSize;比较函数名称计数器
                        repe cmpsb;比较函数名
                        pop rcx
                        .if ZERO?
                                mov r8d,[r11].AddressOfNameOrdinals;读取函数序号表头RVA
                    add r8,r10;计算函数序号表头VA
                    mov cx,word ptr[r8+rcx*2];读取函数RVA索引
                    mov r9d,[r11].AddressOfFunctions
                    add r9,r10
                    mov eax,dword ptr[r9+rcx*4]
                    add rax,r10
                    pop rdi
                                pop rsi
                    ret
                        .endif
                .untilcxz
            pop rdi
            pop rsi
            xor rax,rax;没有该函数
            ret
GetProcAddressByName ENDP

int 3
int 3
int 3
int 3
int 3
int 3

main proc
        ;X64 call时栈必须010H对齐

        LOCAL hFile:QWORD
        LOCAL dwFileSize:QWORD
        LOCAL pDllRaw:QWORD
        LOCAL pDllRaw1:QWORD
        ;       本地调试专用
        invoke CreateFileA,offset filepath,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
        mov hFile,rax
        
        invoke GetFileSize,hFile,NULL
        mov dwFileSize,rax

        invoke VirtualAlloc,NULL,RAX,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE
        mov pDllRaw,rax

        invoke _lread,hFile,pDllRaw,dwFileSize
        
        mov rcx,pDllRaw
        sub rsp,4*8
        call LoadDll
        add rsp,4*8
        ret

main endp
end



[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

收藏
点赞7
打赏
分享
最新回复 (9)
雪    币: 6590
活跃值: (3229)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
htpidk 2023-5-23 12:43
2
1
收藏先,有空再看
雪    币: 1257
活跃值: (1424)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
yllen 2023-5-23 16:12
3
0
上次看你,还是win7那份bootkit 
雪    币: 1651
活跃值: (1420)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
lxsgbin 1 2023-5-23 16:29
4
0
嗯呢
雪    币: 1537
活跃值: (2842)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
zhenwo 1 2023-5-23 22:43
5
0
怀念那个debugman,x64asm luntan
雪    币: 664
活跃值: (652)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tomken 2023-8-19 17:44
6
0
第八个男人 膜拜
雪    币: 19270
活跃值: (28900)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
秋狝 2023-8-19 20:17
7
1
感谢分享
雪    币: 1003
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ptdaxiake 2024-2-5 14:37
8
0
为啥不用c写呢
雪    币: 251
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4essence 2024-2-17 23:28
9
0
强,收藏先
雪    币: 2478
活跃值: (3002)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
satadrover 2024-3-1 16:01
10
0
要这样说的话,我也要发一个12年前用汇编写的加载器
游客
登录 | 注册 方可回帖
返回