-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 14e7a1a
Showing
6 changed files
with
474 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
[package] | ||
name = "shellcode" | ||
version = "0.1.0" | ||
authors = ["Jaxii"] | ||
edition = "2021" | ||
|
||
|
||
[dependencies] | ||
|
||
[profile.release] | ||
panic = "abort" | ||
opt-level = "z" | ||
lto = true | ||
strip = true | ||
codegen-units = 1 | ||
|
||
[dependencies.num] | ||
version = "0.4.0" | ||
default-features = false | ||
|
||
[dependencies.num-traits] | ||
version = "0.2.15" | ||
default-features = false | ||
|
||
[build] | ||
target = "x86_64-pc-windows-msvc" |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
fn main() { | ||
// println!("cargo:rustc-link-arg-bins=/ALIGN:16"); | ||
// println!("cargo:rustc-link-arg-bins=/FILEALIGN:1"); | ||
// Merges empty `.rdata` and `.pdata` into .text section saving a few bytes in data | ||
// directories portion of PE header. | ||
/* | ||
"-C", "link-arg=/MERGE:.edata=.rdata", | ||
"-C", "link-arg=/MERGE:.rustc=.data", | ||
"-C", "link-arg=/MERGE:.rdata=.text", | ||
"-C", "link-arg=/MERGE:.pdata=.text", | ||
*/ | ||
println!("cargo:rustc-link-arg-bins=/MERGE:.edata=.rdata"); | ||
println!("cargo:rustc-link-arg-bins=/MERGE:.rustc=.data"); | ||
println!("cargo:rustc-link-arg-bins=/MERGE:.rdata=.text"); | ||
println!("cargo:rustc-link-arg-bins=/MERGE:.pdata=.text"); | ||
println!("cargo:rustc-link-arg-bins=/MERGE:.pdata=.text"); | ||
// Prevents linking default C runtime libraries. | ||
println!("cargo:rustc-link-arg-bins=/NODEFAULTLIB"); | ||
println!("cargo:rustc-link-arg-bins=/OPT:REF,ICF"); | ||
//println!("cargo:rustc-link-arg-bins=/INTEGRITYCHECK"); breaks executable :( | ||
println!("cargo:rustc-link-arg-bins=/ENTRY:main"); | ||
println!("cargo:rustc-link-arg-bins=/EMITPOGOPHASEINFO"); | ||
println!("cargo:rustc-link-arg-bins=/DEBUG:NONE"); | ||
println!("cargo:rustc-link-arg-bins=/NOLOGO"); | ||
println!("cargo:rustc-link-arg-bins=/NXCOMPAT"); | ||
println!("cargo:rustc-link-arg-bins=/DYNAMICBASE"); | ||
println!("cargo:rustc-link-arg-bins=/MANIFEST:NO"); | ||
// See: https://github.com/mcountryman/min-sized-rust-windows/pull/7 | ||
println!("cargo:rustc-link-arg-bins=/STUB:stub.exe"); | ||
|
||
println!("cargo:rustc-target-feature=-mmx,-sse,+soft-float"); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
#![allow(non_snake_case)] | ||
#![allow(non_camel_case_types)] | ||
#![allow(dead_code)] | ||
|
||
pub enum c_void {} | ||
pub type BOOLEAN = u8; | ||
pub type HANDLE = *mut c_void; | ||
pub type PVOID = *mut c_void; | ||
pub type ULONG = u32; | ||
pub type LPSTR = *mut i8; | ||
#[repr(C)] | ||
pub struct PEB { | ||
pub InheritedAddressSpace: BOOLEAN, | ||
pub ReadImageFileExecOptions: BOOLEAN, | ||
pub BeingDebugged: BOOLEAN, | ||
pub BitField: BOOLEAN, | ||
pub Mutant: HANDLE, | ||
pub ImageBaseAddress: PVOID, | ||
pub Ldr: *mut PEB_LDR_DATA, | ||
pub ProcessParameters: *mut RTL_USER_PROCESS_PARAMETERS, | ||
} | ||
pub type LPCSTR = *const i8; | ||
#[repr(C)] | ||
pub struct PEB_LDR_DATA { | ||
pub Length: ULONG, | ||
pub Initialized: BOOLEAN, | ||
pub SsHandle: HANDLE, | ||
pub InLoadOrderModuleList: LIST_ENTRY, | ||
// ... | ||
} | ||
|
||
pub type PLDR_DATA_TABLE_ENTRY = *const LDR_DATA_TABLE_ENTRY; | ||
#[repr(C)] | ||
pub struct LDR_DATA_TABLE_ENTRY { | ||
pub InLoadOrderModuleList: LIST_ENTRY, | ||
pub InMemoryOrderModuleList: LIST_ENTRY, | ||
pub InInitializationOrderModuleList: LIST_ENTRY, | ||
pub BaseAddress: PVOID, | ||
pub EntryPoint: PVOID, | ||
pub SizeOfImage: ULONG, | ||
pub FullDllName: UNICODE_STRING, | ||
pub BaseDllName: UNICODE_STRING, | ||
// ... | ||
} | ||
|
||
pub type USHORT = u16; | ||
pub type PWCH = *mut u16; | ||
pub type DWORD = u32; | ||
pub type WORD = u16; | ||
pub type ULONGLONG = u64; | ||
pub type BYTE = u8; | ||
pub type LONG = u32; | ||
|
||
#[repr(C)] | ||
pub struct UNICODE_STRING { | ||
pub Length: USHORT, | ||
pub MaximumLength: USHORT, | ||
pub Buffer: PWCH, | ||
} | ||
|
||
#[repr(C)] | ||
pub struct LIST_ENTRY { | ||
pub Flink: *mut LIST_ENTRY, | ||
pub Blink: *mut LIST_ENTRY, | ||
} | ||
#[repr(C)] | ||
pub struct RTL_USER_PROCESS_PARAMETERS { | ||
pub MaximumLength: ULONG, | ||
pub Length: ULONG, | ||
pub Flags: ULONG, | ||
pub DebugFlags: ULONG, | ||
pub ConsoleHandle: HANDLE, | ||
pub ConsoleFlags: ULONG, | ||
pub StandardInput: HANDLE, | ||
pub StandardOutput: HANDLE, | ||
pub StandardError: HANDLE, | ||
} | ||
|
||
type PULONG = *mut ULONG; | ||
#[repr(C)] | ||
pub struct IO_STATUS_BLOCK { | ||
_1: IO_STATUS_BLOCK_u, | ||
_2: PULONG, | ||
} | ||
/// A specialized `Result` type for NT operations. | ||
pub type Result<T> = ::core::result::Result<T, Status>; | ||
|
||
/// NT Status code. | ||
#[repr(C)] | ||
#[derive(Clone, Copy)] | ||
pub enum Status { | ||
success = 0, | ||
unsuccessful = 0xC0000001, | ||
} | ||
|
||
#[repr(C)] | ||
pub union IO_STATUS_BLOCK_u { | ||
_1: NTSTATUS, | ||
_2: PVOID, | ||
} | ||
pub type NTSTATUS = Status; | ||
type HMODULE = HINSTANCE; | ||
type HINSTANCE = *mut HINSTANCE__; | ||
pub enum HINSTANCE__ {} | ||
// ==== | ||
#[repr(C)] | ||
pub struct IMAGE_DATA_DIRECTORY { | ||
pub VirtualAddress: DWORD, | ||
pub Size: DWORD, | ||
} | ||
#[repr(C)] | ||
pub struct IMAGE_DOS_HEADER { | ||
pub e_magic: WORD, | ||
pub e_cblp: WORD, | ||
pub e_cp: WORD, | ||
pub e_crlc: WORD, | ||
pub e_cparhdr: WORD, | ||
pub e_minalloc: WORD, | ||
pub e_maxalloc: WORD, | ||
pub e_ss: WORD, | ||
pub e_sp: WORD, | ||
pub e_csum: WORD, | ||
pub e_ip: WORD, | ||
pub e_cs: WORD, | ||
pub e_lfarlc: WORD, | ||
pub e_ovno: WORD, | ||
pub e_res: [WORD; 4], | ||
pub e_oemid: WORD, | ||
pub e_oeminfo: WORD, | ||
pub e_res2: [WORD; 10], | ||
pub e_lfanew: LONG, | ||
} | ||
|
||
#[repr(C)] | ||
pub struct IMAGE_EXPORT_DIRECTORY { | ||
pub Characteristics: DWORD, | ||
pub TimeDateStamp: DWORD, | ||
pub MajorVersion: WORD, | ||
pub MinorVersion: WORD, | ||
pub Name: DWORD, | ||
pub Base: DWORD, | ||
pub NumberOfFunctions: DWORD, | ||
pub NumberOfNames: DWORD, | ||
pub AddressOfFunctions: DWORD, | ||
pub AddressOfNames: DWORD, | ||
pub AddressOfNameOrdinals: DWORD, | ||
} | ||
type ULONG_PTR = usize; | ||
|
||
pub const IMAGE_DOS_SIGNATURE: WORD = 0x5A4D; | ||
|
||
pub type IMAGE_NT_HEADERS = IMAGE_NT_HEADERS64; | ||
#[repr(C)] | ||
pub struct IMAGE_NT_HEADERS64 { | ||
pub Signature: DWORD, | ||
pub FileHeader: IMAGE_FILE_HEADER, | ||
pub OptionalHeader: IMAGE_OPTIONAL_HEADER64, | ||
} | ||
|
||
#[repr(C)] | ||
pub struct IMAGE_FILE_HEADER { | ||
pub Machine: WORD, | ||
pub NumberOfSections: WORD, | ||
pub TimeDateStamp: DWORD, | ||
pub PointerToSymbolTable: DWORD, | ||
pub NumberOfSymbols: DWORD, | ||
pub SizeOfOptionalHeader: WORD, | ||
pub Characteristics: WORD, | ||
} | ||
#[repr(C)] | ||
pub struct IMAGE_OPTIONAL_HEADER64 { | ||
pub Magic: WORD, | ||
pub MajorLinkerVersion: BYTE, | ||
pub MinorLinkerVersion: BYTE, | ||
pub SizeOfCode: DWORD, | ||
pub SizeOfInitializedData: DWORD, | ||
pub SizeOfUninitializedData: DWORD, | ||
pub AddressOfEntryPoint: DWORD, | ||
pub BaseOfCode: DWORD, | ||
pub ImageBase: ULONGLONG, | ||
pub SectionAlignment: DWORD, | ||
pub FileAlignment: DWORD, | ||
pub MajorOperatingSystemVersion: WORD, | ||
pub MinorOperatingSystemVersion: WORD, | ||
pub MajorImageVersion: WORD, | ||
pub MinorImageVersion: WORD, | ||
pub MajorSubsystemVersion: WORD, | ||
pub MinorSubsystemVersion: WORD, | ||
pub Win32VersionValue: DWORD, | ||
pub SizeOfImage: DWORD, | ||
pub SizeOfHeaders: DWORD, | ||
pub CheckSum: DWORD, | ||
pub Subsystem: WORD, | ||
pub DllCharacteristics: WORD, | ||
pub SizeOfStackReserve: ULONGLONG, | ||
pub SizeOfStackCommit: ULONGLONG, | ||
pub SizeOfHeapReserve: ULONGLONG, | ||
pub SizeOfHeapCommit: ULONGLONG, | ||
pub LoaderFlags: DWORD, | ||
pub NumberOfRvaAndSizes: DWORD, | ||
pub DataDirectory: [IMAGE_DATA_DIRECTORY; 16], | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
#![allow(non_snake_case)] | ||
#![allow(non_camel_case_types)] | ||
#![allow(non_upper_case_globals)] | ||
#![allow(overflowing_literals)] | ||
#![no_std] | ||
#![no_main] | ||
#![windows_subsystem="windows"] | ||
#![feature(type_ascription)] | ||
|
||
|
||
use core::arch::asm; | ||
use core::ptr::{null_mut}; | ||
mod binds; | ||
mod utils; | ||
use binds::*; | ||
use utils::*; | ||
#[panic_handler] | ||
fn panic(_: &core::panic::PanicInfo) -> ! { | ||
loop {} | ||
} | ||
// const KERNEL32_DLL: &str = concat!("KERNEL32.DLL", "\0"); | ||
const USER32_DLL: &str = concat!("user32.dll", "\0"); | ||
const LoadLibraryA_: &str = concat!("LoadLibraryA", "\0"); | ||
const GetProcAddress_: &str = concat!("GetProcAddress", "\0"); | ||
const MessageBoxA_: &str = concat!("MessageBoxA", "\0"); | ||
//const GetComputerName_: &str = concat!("GetComputerName", "\0"); | ||
|
||
pub type LoadLibraryAFn = extern "system" fn(lpFileName: LPCSTR) -> PVOID; | ||
pub type GetProcAddressFn = extern "system" fn(hmodule: PVOID, name: LPCSTR) -> PVOID; | ||
pub type MessageBoxAFn = extern "system" fn(h: PVOID, text: LPCSTR, cation: LPCSTR, t: u32) -> u32; | ||
//pub type GetComputerNameFn = extern "system" fn(idk: LPSTR, idk2: DWORD) -> u32; | ||
#[no_mangle] | ||
pub extern "C" fn main() -> ! { | ||
unsafe { | ||
asm!("mov rcx, 0", "mov rdx, 0",); | ||
} | ||
let KERNEL32_STR: [u16; 13] = [75, 69, 82, 78, 69, 76, 51, 50, 46, 68, 76, 76, 0]; | ||
let kernel32_ptr = get_module_by_name(KERNEL32_STR.as_ptr()); | ||
let load_library_ptr = get_func_by_name(kernel32_ptr, LoadLibraryA_.as_ptr()); | ||
let get_proc = get_func_by_name(kernel32_ptr, GetProcAddress_.as_ptr()); | ||
// let get_name = get_func_by_name(kernel32_ptr, GetComputerName_.as_ptr()); | ||
let LoadLibraryA: LoadLibraryAFn = unsafe { core::mem::transmute(load_library_ptr) }; | ||
|
||
unsafe { asm!("and rsp, ~0xf") }; | ||
let u32_dll = LoadLibraryA(USER32_DLL.as_ptr() as *const i8); | ||
let GetProcAddress: GetProcAddressFn = unsafe { core::mem::transmute(get_proc) }; | ||
let message_box_ptr = GetProcAddress(u32_dll, MessageBoxA_.as_ptr() as *const i8); | ||
let MessageBoxA: MessageBoxAFn = unsafe { core::mem::transmute(message_box_ptr) }; | ||
// let GetComputerName: GetComputerNameFn = unsafe { core::mem::transmute(get_name)}; | ||
// let name_output = GetComputerName("\0".as_ptr() as *mut i8: LPSTR, 32767); | ||
MessageBoxA( | ||
null_mut(), | ||
"Message\0".as_ptr() as *const i8, | ||
"Title\0".as_ptr() as _, | ||
0x20, | ||
); | ||
loop {} | ||
} | ||
|
||
fn get_module_by_name(module_name: *const u16) -> PVOID { | ||
let peb: *mut PEB; | ||
unsafe { | ||
asm!( | ||
"mov {}, gs:[0x60]", | ||
out(reg) peb, | ||
); | ||
let ldr = (*peb).Ldr; | ||
let list_entry = &((*ldr).InLoadOrderModuleList); | ||
let mut cur_module: *const LDR_DATA_TABLE_ENTRY = &list_entry as *const _ as *const _; | ||
loop { | ||
if cur_module.is_null() || (*cur_module).BaseAddress.is_null() { | ||
//todo: break | ||
} | ||
let cur_name = (*cur_module).BaseDllName.Buffer; | ||
if !cur_name.is_null() { | ||
if compare_raw_str(module_name, cur_name) { | ||
return (*cur_module).BaseAddress; | ||
} | ||
} | ||
let flink = (*cur_module).InLoadOrderModuleList.Flink; | ||
cur_module = flink as *const LDR_DATA_TABLE_ENTRY; | ||
} | ||
} | ||
} | ||
|
||
fn get_func_by_name(module: PVOID, func_name: *const u8) -> PVOID { | ||
let idh: *const IMAGE_DOS_HEADER = module as *const _; | ||
unsafe { | ||
if (*idh).e_magic != IMAGE_DOS_SIGNATURE { | ||
return null_mut(); | ||
} | ||
let e_lfanew = (*idh).e_lfanew; | ||
let nt_headers: *const IMAGE_NT_HEADERS = | ||
(module as *const u8).offset(e_lfanew as isize) as *const _; | ||
let op_header = &(*nt_headers).OptionalHeader; | ||
let virtual_addr = (&op_header.DataDirectory[0]).VirtualAddress; | ||
let export_dir: *const IMAGE_EXPORT_DIRECTORY = | ||
(module as *const u8).offset(virtual_addr as _) as _; | ||
let number_of_names = (*export_dir).NumberOfNames; | ||
let addr_of_funcs = (*export_dir).AddressOfFunctions; | ||
let addr_of_names = (*export_dir).AddressOfNames; | ||
let addr_of_ords = (*export_dir).AddressOfNameOrdinals; | ||
for i in 0..number_of_names { | ||
let name_rva_p: *const DWORD = | ||
(module as *const u8).offset((addr_of_names + i * 4) as isize) as *const _; | ||
let name_index_p: *const WORD = | ||
(module as *const u8).offset((addr_of_ords + i * 2) as isize) as *const _; | ||
let name_index = name_index_p.as_ref().unwrap(); | ||
let mut off: u32 = (4 * name_index) as u32; | ||
off = off + addr_of_funcs; | ||
let func_rva: *const DWORD = (module as *const u8).offset(off as _) as *const _; | ||
|
||
let name_rva = name_rva_p.as_ref().unwrap(); | ||
let curr_name = (module as *const u8).offset(*name_rva as isize); | ||
|
||
if *curr_name == 0 { | ||
continue; | ||
} | ||
if compare_raw_str(func_name, curr_name) { | ||
let res = (module as *const u8).offset(*func_rva as isize); | ||
return res as _; | ||
} | ||
} | ||
} | ||
return null_mut(); | ||
} |
Oops, something went wrong.