可以转成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