可以转成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
更多【发一个11年前写的纯汇编X64 PELoader】相关视频教程:www.yxfzedu.com