Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaxii committed Jun 24, 2022
0 parents commit 14e7a1a
Show file tree
Hide file tree
Showing 6 changed files with 474 additions and 0 deletions.
26 changes: 26 additions & 0 deletions Cargo.toml
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"
32 changes: 32 additions & 0 deletions build.rs
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");
}
202 changes: 202 additions & 0 deletions src/binds.rs
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],
}
126 changes: 126 additions & 0 deletions src/main.rs
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();
}
Loading

0 comments on commit 14e7a1a

Please sign in to comment.