Last active
September 2, 2020 23:01
-
-
Save beans42/0f6926436954722270670163245a2c0f to your computer and use it in GitHub Desktop.
This file contains 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
//beans42 / SexOffenderSally#0660 | |
//COMPILE IN x64!! | |
#define WIN32_LEAN_AND_MEAN | |
#include <Windows.h> | |
#include <iostream> | |
template<typename func_prototype, size_t shellcode_length> | |
func_prototype* make_func(const char(&shellcode)[shellcode_length]) { | |
const auto func_ptr = (func_prototype*)&shellcode; | |
DWORD old_protect; | |
VirtualProtect(func_ptr, shellcode_length, PAGE_EXECUTE_READWRITE, &old_protect); | |
return func_ptr; | |
} | |
template<typename T, size_t N> | |
constexpr size_t arr_size(T(&)[N]) { return N; } | |
int main() { | |
const auto power = make_func<int(int x, int n)>("\xB8\x01\x00\x00\x00\x31\xDB\x0F\xAF\xC1\xFF\xC3\x39\xD3\x7C\xF7\xC3"); | |
const auto fib_fill = make_func<void(int* arr, int n)>("\x41\xB8\x01\x00\x00\x00\x45\x31\xC9\x4D\x31\xDB\x46\x89\x0C\x99\x67\x47\x8D\x14\x08\x45\x89\xC8\x45\x89\xD1\x41\xFF\xC3\x41\x39\xD3\x7C\xE9\xC3"); | |
//add printf format strings just after end of shellcode and patch placeholder bytes (0x6969696969696969) with printf address | |
const char print_arr_code[] = "\x53\x41\x54\x41\x55\x41\x56\x48\x83\xEC\x20\x49\xBE\x69\x69\x69\x69\x69\x69\x69\x69\x49\x89\xCC\x49\x89\xD5\x48\x31\xDB\x48\x8D\x0D\x25\x00\x00\x00\x41\x8B\x14\x9C\x41\xFF\xD6\x48\xFF\xC3\x4C\x39\xEB\x7C\xEA\x48\x8D\x0D\x13\x00\x00\x00\x41\xFF\xD6\x48\x83\xC4\x20\x41\x5E\x41\x5D\x41\x5C\x5B\xC3%d \0\n\0"; | |
*(uint64_t*)&print_arr_code[13] = (uint64_t)printf; | |
const auto print_arr = make_func<void(int* arr, int n)>(print_arr_code); | |
int arr[10]; | |
fib_fill(arr, arr_size(arr)); | |
print_arr(arr, arr_size(arr)); | |
std::cout << power(2, 16) << '\n'; | |
} | |
//sources for the above shellcode, you can assemble with something like https://defuse.ca/online-x86-assembler.htm or use your own assembler | |
/* power | |
mov eax, 1 | |
xor ebx, ebx | |
mult_loop: | |
imul eax, ecx | |
inc ebx | |
cmp ebx, edx | |
jl mult_loop | |
ret | |
*/ | |
/* fib_fill | |
mov r8d, 1 | |
xor r9d, r9d | |
xor r11, r11 | |
fibb_loop: | |
mov [rcx + r11 * 4], r9d | |
lea r10d, [r8d + r9d] | |
mov r8d, r9d | |
mov r9d, r10d | |
inc r11d | |
cmp r11d, edx | |
jl fibb_loop | |
ret | |
*/ | |
/* print_arr # more complex subroutine that calls an external function and needs to allocate shadow-space for it | |
# save non-volatile registers (could use stack but it would be more code and we only need 4 'locals') | |
push rbx # counter | |
push r12 # home for rcx (array pointer) | |
push r13 # home for rdx (array size) | |
push r14 # stores printf address so we only have to patch once | |
sub rsp, 0x20 # allocate 32 (4 * 8) bytes for printf's register parameter shadow-space/home-space | |
mov r14, 0x6969696969696969 # placeholder that we will patch with the address of printf | |
mov r12, rcx | |
mov r13, rdx | |
xor rbx, rbx | |
print_loop: | |
lea rcx, [rip + 37] # pointing to byte after ret, will hold format "%d " for printf call | |
mov edx, [r12 + rbx * 4] | |
call r14 | |
inc rbx | |
cmp rbx, r13 | |
jl print_loop | |
lea rcx, [rip + 19] # pointing to 5 bytes after ret, will hold format "\n" so we go to a newline after we print all the numbers | |
call r14 | |
add rsp, 0x20 #de-allocate those 32 bytes | |
pop r14 | |
pop r13 | |
pop r12 | |
pop rbx | |
ret | |
*/ | |
/* print_arr # same as above but we use stack instead | |
push rbp | |
mov rbp, rsp | |
sub rsp, 64 # 32 bytes for local variables, 32 bytes for shadow-space of called functions (ie printf) | |
mov r8, 0x6969696969696969 | |
mov [rbp - 8], r8 | |
mov [rbp - 16], rcx | |
mov [rbp - 24], rdx | |
mov qword ptr [rbp - 32], 0 | |
print_loop: | |
mov r8, [rbp - 16] | |
mov r9, [rbp - 32] | |
lea rcx, [rip + 40] | |
mov edx, [r8 + r9 * 4] | |
call [rbp - 8] | |
inc qword ptr [rbp - 32] | |
mov r8, [rbp - 24] | |
cmp [rbp - 32], r8 | |
jl print_loop | |
lea rcx, [rip + 16] | |
call [rbp - 8] | |
add rsp, 64 # de-allocate local variables and callee shadow-space | |
mov rsp, rbp | |
pop rbp | |
ret | |
*/ | |
/* print_arr # yet another version but now instead of 32 bytes of local variables, we put rcx and rdx into *our* function's shadow-space | |
push rbp | |
mov rbp, rsp | |
sub rsp, 48 # 16 bytes for local variables, 32 bytes for shadow-space of called functions (ie printf) | |
mov [rbp + 24], rcx # store params in *our* shadow-space | |
mov [rbp + 32], rdx | |
mov r8, 0x6969696969696969 | |
mov [rbp - 8], r8 | |
mov qword ptr [rbp - 16], 0 | |
print_loop: | |
mov r8, [rbp + 24] | |
mov r9, [rbp - 16] | |
lea rcx, [rip + 40] | |
mov edx, [r8 + r9 * 4] | |
call [rbp - 8] | |
inc qword ptr [rbp - 16] | |
mov r8, [rbp + 32] | |
cmp [rbp - 16], r8 | |
jl print_loop | |
lea rcx, [rip + 16] | |
call [rbp - 8] | |
add rsp, 48 | |
mov rsp, rbp | |
pop rbp | |
ret | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment