├── .github └── workflows │ └── ci.yaml ├── .gitignore ├── .idea ├── .gitignore ├── modules.xml ├── mwemu.iml └── vcs.xml ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── Makefile ├── README.md ├── docs ├── ARGUMENTS.md ├── COMPILATION.md ├── CONSOLE.md ├── FIXES.md ├── GULOADER.md ├── ICED-X86.md ├── PROGRAMATICALLY.md └── TODO.md ├── libmwemu ├── .gitignore ├── Cargo.toml ├── README.md └── src │ ├── banzai.rs │ ├── breakpoint.rs │ ├── colors.rs │ ├── config.rs │ ├── console.rs │ ├── constants.rs │ ├── context32.rs │ ├── context64.rs │ ├── eflags.rs │ ├── elf32.rs │ ├── elf64.rs │ ├── emu.rs │ ├── endpoint.rs │ ├── engine │ ├── logic.rs │ └── mod.rs │ ├── err.rs │ ├── exception.rs │ ├── exception_type.rs │ ├── flags.rs │ ├── fpu.rs │ ├── hooks.rs │ ├── inline.rs │ ├── lib.rs │ ├── macros.rs │ ├── maps │ ├── mem64.rs │ └── mod.rs │ ├── ntapi32.rs │ ├── pe32.rs │ ├── pe64.rs │ ├── peb32.rs │ ├── peb64.rs │ ├── regs64.rs │ ├── script.rs │ ├── serialization.rs │ ├── structures.rs │ ├── syscall32.rs │ ├── syscall64.rs │ ├── tests.rs │ ├── winapi32 │ ├── advapi32.rs │ ├── crypt32.rs │ ├── dnsapi.rs │ ├── helper.rs │ ├── iphlpapi.rs │ ├── kernel32.rs │ ├── kernelbase.rs │ ├── libgcc.rs │ ├── mod.rs │ ├── mscoree.rs │ ├── msvcrt.rs │ ├── ntdll.rs │ ├── oleaut32.rs │ ├── shlwapi.rs │ ├── user32.rs │ ├── wincrt.rs │ ├── wininet.rs │ └── ws2_32.rs │ └── winapi64 │ ├── advapi32.rs │ ├── comctl32.rs │ ├── comctl64.rs │ ├── dnsapi.rs │ ├── gdi32.rs │ ├── kernel32.rs │ ├── kernelbase.rs │ ├── mod.rs │ ├── msvcrt.rs │ ├── ntdll.rs │ ├── ole32.rs │ ├── oleaut32.rs │ ├── shell32.rs │ ├── shlwapi.rs │ ├── user32.rs │ ├── uxtheme.rs │ ├── wincrt.rs │ ├── winhttp.rs │ ├── wininet.rs │ └── ws2_32.rs ├── maps32 ├── RstrtMgr.dll ├── WINSPOOL.DRV ├── advapi32.dll ├── api-ms-win-crt-environment-l1-1-0.dll ├── api-ms-win-crt-heap-l1-1-0.dll ├── api-ms-win-crt-locale-l1-1-0.dll ├── api-ms-win-crt-math-l1-1-0.dll ├── api-ms-win-crt-private-l1-1-0.dll ├── api-ms-win-crt-runtime-l1-1-0.dll ├── api-ms-win-crt-stdio-l1-1-0.dll ├── banzai.csv ├── bcrypt.dll ├── combase.dll ├── comctl.dll ├── comctl32.dll ├── comdlg32.dll ├── crypt32.dll ├── d3d11.dll ├── dbghelp.dll ├── dnsapi.dll ├── esent.dll ├── gdi32.dll ├── gdiplus.dll ├── iphlpapi.dll ├── kernel32.dll ├── kernelbase.dll ├── libgcc_s_dw2-1.dll ├── loader.exe ├── lz32.dll ├── m10000.bin ├── m20000.bin ├── mpr.dll ├── mscoree.dll ├── msvcp140.dll ├── msvcp_win.dll ├── msvcrt.dll ├── netapi32.dll ├── noname.dll ├── nsi.dll ├── ntdll.dll ├── ole32.dll ├── oleacc.dll ├── oleaut32.dll ├── olepro32.dll ├── psapi.dll ├── pstorec.dll ├── rasapi32.dll ├── shell32.dll ├── shlwapi.dll ├── ucrtbase.dll ├── user32.dll ├── userenv.dll ├── usp10.dll ├── uxtheme.dll ├── vaultcli.dll ├── vcruntime140.dll ├── version.dll ├── vtcheck.py ├── winhttp.dll ├── wininet.dll ├── winmm.dll ├── winspool.drv.dll ├── wintrust.dll ├── ws2_32.dll └── wsock32.dll ├── maps64 ├── advapi32.dll ├── api-ms-win-core-crt-l1-1-0.dll ├── api-ms-win-core-crt-l2-1-0.dll ├── api-ms-win-core-delayload-l1-1-0.dll ├── api-ms-win-core-delayload-l1-1-1.dll ├── api-ms-win-core-errorhandling-l1-1-0.dll ├── api-ms-win-core-file-l1-2-0.dll ├── api-ms-win-core-file-l2-1-0.dll ├── api-ms-win-core-handle-l1-1-0.dll ├── api-ms-win-core-heap-l1-1-0.dll ├── api-ms-win-core-heap-l2-1-0.dll ├── api-ms-win-core-heap-obsolete-l1-1-0.dll ├── api-ms-win-core-io-l1-1-0.dll ├── api-ms-win-core-libraryloader-l1-2-0.dll ├── api-ms-win-core-localization-l1-2-0.dll ├── api-ms-win-core-memory-l1-1-0.dll ├── api-ms-win-core-processthreads-l1-1-0.dll ├── api-ms-win-core-processthreads-l1-1-1.dll ├── api-ms-win-core-profile-l1-1-0.dll ├── api-ms-win-core-registry-l1-1-0.dll ├── api-ms-win-core-string-l1-1-0.dll ├── api-ms-win-core-synch-l1-1-0.dll ├── api-ms-win-core-synch-l1-2-0.dll ├── api-ms-win-core-sysinfo-l1-1-0.dll ├── api-ms-win-core-timezone-l1-1-0.dll ├── api-ms-win-core-util-l1-1-0.dll ├── api-ms-win-core-xstate-l2-1-0.dll ├── api-ms-win-crt-conio-l1-1-0.dll ├── api-ms-win-crt-convert-l1-1-0.dll ├── api-ms-win-crt-environment-l1-1-0.dll ├── api-ms-win-crt-filesystem-l1-1-0.dll ├── api-ms-win-crt-heap-l1-1-0.dll ├── api-ms-win-crt-locale-l1-1-0.dll ├── api-ms-win-crt-math-l1-1-0.dll ├── api-ms-win-crt-multibyte-l1-1-0.dll ├── api-ms-win-crt-private-l1-1-0.dll ├── api-ms-win-crt-process-l1-1-0.dll ├── api-ms-win-crt-runtime-l1-1-0.dll ├── api-ms-win-crt-stdio-l1-1-0.dll ├── api-ms-win-crt-string-l1-1-0.dll ├── api-ms-win-crt-time-l1-1-0.dll ├── api-ms-win-crt-utility-l1-1-0.dll ├── api-ms-win-eventing-classicprovider-l1-1-0.dll ├── api-ms-win-eventing-provider-l1-1-0.dll ├── api-ms-win-security-base-l1-1-0.dll ├── api-ms-win-security-credentials-l1-1-0.dll ├── avifil32.dll ├── bcrypt.dll ├── bcryptprimitives.dll ├── cabinet.dll ├── combase.dll ├── comctl32.dll ├── dnsapi.dll ├── dwmapi.dll ├── gdi32.dll ├── iphlpapi.dll ├── kernel.appcore.dll ├── kernel32.dll ├── kernelbase.dll ├── linker.bin_prev ├── linux_dynamic_stack.bin.old ├── loader.exe ├── m10000.bin ├── m20000.bin ├── m520000.bin ├── m53b000.bin ├── mpr.dll ├── mscoree.dll ├── msctf.dll ├── msimg32.dll ├── msvcp140.dll ├── msvcrt.dll ├── mswsock.dll ├── netapi32.dll ├── ntdll.dll ├── ole32.dll ├── oleaut32.dll ├── profapi.dll ├── psapi.dll ├── rpcrt4.dll ├── secur32.dll ├── shell32.dll ├── shfolder.dll ├── shlwapi.dll ├── teb.bin ├── user32.dll ├── userenv.dll ├── uxtheme.dll ├── vcruntime140.dll ├── version.dll ├── windows.storage.dll ├── winhttp.dll ├── wininet.dll ├── winmm.dll ├── wintypes.dll ├── ws2_32.dll └── wtsapi32.dll ├── mwemu ├── .gitignore ├── Cargo.toml └── src │ └── main.rs ├── pics ├── basic_shellcode1.png ├── basic_shellcode2.png ├── cobalt_strike.png ├── console_help.png ├── exception.png ├── guloader1.png ├── maps.png ├── memdump.png ├── metasploit_api_loader.png ├── metasploit_rshell.png ├── msf_encoded.png ├── msgbox.png ├── mwemu_logo.png ├── shikata.png ├── structure3.png ├── structures.png ├── structures2.png └── usage.png ├── pymwemu ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── DOCUMENTATION.md ├── README.md ├── __init__.py ├── examples │ ├── danabot_rsa.ipynb │ ├── raccoon_strings.ipynb │ ├── scripts │ │ ├── .ipynb_checkpoints │ │ │ └── test-checkpoint.py │ │ ├── api_implementation.py │ │ ├── danabot_crypto.py │ │ ├── danabot_extract.py │ │ ├── danabot_get_string_emu.py │ │ ├── danabot_int_deobfus_emu.py │ │ ├── emu_pwer.py │ │ ├── emu_rat.py │ │ ├── gozi_decryptbss_emu.py │ │ ├── gozi_dga.py │ │ ├── raccoon_strings.py │ │ ├── ssl_key128_gen.py │ │ ├── test.py │ │ ├── vidar_strings.py │ │ ├── vidar_strings2.py │ │ ├── xloader_dexor.py │ │ └── xloader_keygen.py │ └── xloader_keygen.ipynb ├── pyproject.toml └── src │ └── lib.rs ├── script_examples ├── README.md ├── call.mwemu ├── control_flow.mwemu ├── danabot2.mwemu ├── danabot_extract.mwemu ├── danabot_string.mwemu ├── danabot_url.mwemu ├── loops.mwemu ├── memory.mwemu ├── raccoon.mwemu ├── registers.mwemu ├── test.mwemu └── vidar.mwemu ├── scripts ├── build-args.py ├── combine-dumps.py ├── diff-trace.py ├── enigma-protector.sh ├── enigma-protector2.sh ├── ghidra_mwemu.py └── trace-converter.py └── tools └── resources └── rsrc64.rs /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: Rust CI 2 | 3 | on: 4 | pull_request: 5 | branches: [ "main" ] 6 | 7 | env: 8 | CARGO_TERM_COLOR: always 9 | 10 | jobs: 11 | check: 12 | name: Check 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - name: Install Rust toolchain 18 | uses: dtolnay/rust-toolchain@stable 19 | with: 20 | components: rustfmt, clippy 21 | 22 | - name: Cache dependencies 23 | uses: actions/cache@v3 24 | with: 25 | path: | 26 | ~/.cargo/registry 27 | ~/.cargo/git 28 | target 29 | key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} 30 | 31 | # TODO: fail pipeline if formatting fails 32 | - name: Check formatting 33 | run: cargo fmt --all -- --check || true 34 | 35 | # TODO: fail pipeline if clippy fails 36 | - name: Run clippy 37 | run: cargo clippy -- -D warnings || true 38 | 39 | - name: Build 40 | run: cargo build --verbose 41 | 42 | - name: Run tests 43 | run: cargo test --verbose -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .gitconfig 3 | shellcodes32/ 4 | shellcodes64/ 5 | .DS_Store 6 | x 7 | *.swp 8 | *.idb 9 | test/ 10 | .venv/ 11 | dumps/ 12 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/mwemu.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | members = [ 4 | "pymwemu", 5 | "libmwemu", 6 | "mwemu" 7 | ] 8 | 9 | [profile.release] 10 | debug = 2 11 | panic = 'unwind' 12 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | cargo build --release 3 | -------------------------------------------------------------------------------- /docs/COMPILATION.md: -------------------------------------------------------------------------------- 1 | # Compilaiton 2 | 3 | The argument parser library require a recent compiler use rustup: 4 | 5 | https://rustup.rs/ 6 | 7 | ```bash 8 | git clone git@github.com:sha0coder/mwemu.git 9 | cd mwemu 10 | cargo build --release 11 | target/release/mwemu --help 12 | ``` 13 | -------------------------------------------------------------------------------- /docs/CONSOLE.md: -------------------------------------------------------------------------------- 1 | # Console 2 | 3 | ## Spawn the console 4 | 5 | Every line printed starts with a number that represent an emulation moment, its possible to spawn a console a specific moment doing for example this: 6 | 7 | ```bash 8 | target/release/mwemu -f shellcode.bin -vv -c 1000 9 | ``` 10 | 11 | This is going to step 1000 instructions and then spawn the console on that moment. 12 | 13 | ## Step, Continue and Quit 14 | 15 | Pressing `enter` the emulator perform steps into, pressing `c` it continues the emulation until a breakpoint or an exception or the end of the emulation. 16 | 17 | To quit the console just press q 18 | 19 | ## Registers 20 | 21 | `r` command display all the registers, but if a register name is specified more information is provided ie: `r esi` 22 | 23 | ``` 24 | =>r esi 25 | esi: 0x775b1244 2002457156 'Zon' (ntdll_text) 26 | ``` 27 | 28 | The info displayed is register: value in hex, value in decimal, string pointed and memory map. 29 | 30 | To change a register press `rc` and enter, then specify the register name, enter again, and then the new value. 31 | 32 | For changing the EIP to redirect the emulator to another place press command `eip` 33 | 34 | ## CPU Flags 35 | 36 | Press `f` to show all the flags, and `fc` for clearing all the flags. Its possible to enable and disable the flag zero with command `fz` and toggle enable/disable sign with `fs` 37 | 38 | ## Breakpoints 39 | 40 | Its only possible to set one breakpoint of each type, but there are several types. 41 | 42 | type `bc` to clear the breakpoing, `ba` to set a breakpoint on address and `bi` to set a breapoing on an emulation moment id. 43 | 44 | Its also possible to set a memory breakpoint on read `bmr` and write `bmw` 45 | 46 | The command `b` list the breakponts: 47 | ``` 48 | =>b 49 | break on address: 0x3c00e4 50 | break on instruction: 0 51 | break on memory read: 0x0 52 | break on memory write: 0x0 53 | ``` 54 | 55 | ## Stack and Variables 56 | 57 | press `s` to see the stack values, and press `v` to se the local variables, both are stored on a memory map named `stack` 58 | 59 | Its possible to push values to the stack for example for preparing parameter to call another function, use `push` command or `pop` command to extract a value from the stack. 60 | 61 | For example push params to the stack and redirect the flow to a function with `eip` command. 62 | 63 | ## FPU 64 | 65 | Press `fpu` command to view the FPU environment. 66 | 67 | ## Memory maps 68 | 69 | Use `m` command to see all the mapped memory maps. Its possible to create a new memory map with `mc` command: 70 | 71 | ``` 72 | =>mc 73 | name =>testmap 74 | base address =>0x5f000000 75 | ``` 76 | 77 | If we have an address and we want to figure-out in which map pertain that address, use memory name `mn` command. 78 | For Loading files to the virtual memory system use `ml` 79 | 80 | ``` 81 | =>ml 82 | map name=>testmap 83 | filename=>/etc/passwd 84 | => 85 | ``` 86 | 87 | To see the maps allocated by the shellcode use `ma` for memory allocations. 88 | 89 | Its possible to compute the md5sum of a memory map with command `md5` 90 | 91 | ## Memory read and write 92 | 93 | Reading specific dword, word or byte can be done with command `mr` for example: 94 | 95 | ``` 96 | =>mr 97 | memory argument=>dword ptr [esi] 98 | 0x775b1244: 0x656e6f5a 99 | => 100 | ``` 101 | 102 | In same way can be written a value to the memory with `mw`: 103 | 104 | ``` 105 | =>mw 106 | memory argument=>dword ptr [esi] 107 | value=>0x1234 108 | done. 109 | => 110 | ``` 111 | 112 | ## Memory dump 113 | 114 | It's quite useful the memory dump command `md` to see the hex bytes and printable strings. 115 | 116 | ``` 117 | =>md 118 | address=>0x775b1244 119 | 34 12 00 00 00 52 74 6c 52 65 73 65 74 52 74 6c 4....RtlResetRtl 120 | 54 72 61 6e 73 6c 61 74 69 6f 6e 73 00 52 74 6c Translations.Rtl 121 | 52 65 73 74 6f 72 65 4c 61 73 74 57 69 6e 33 32 RestoreLastWin32 122 | 45 72 72 6f 72 00 52 74 6c 52 65 74 72 69 65 76 Error.RtlRetriev 123 | 65 4e 74 55 73 65 72 50 66 6e 00 52 74 6c 52 65 eNtUserPfn.RtlRe 124 | 76 65 72 74 4d 65 6d 6f 72 79 53 74 72 65 61 6d vertMemoryStream 125 | 00 52 74 6c 52 75 6e 44 65 63 6f 64 65 55 6e 69 .RtlRunDecodeUni 126 | 63 6f 64 65 53 74 72 69 6e 67 00 52 74 6c 52 75 codeString.RtlRu 127 | ``` 128 | 129 | Also it's possible to dump to disk with `mdd` command. 130 | 131 | If you want to dump an ascii string `mds` and wide string with `mdw` 132 | 133 | The command `mrd` for memory read dword dumps a list of dwords. And `mrq` for read a list of qwords. 134 | 135 | 136 | ## Search 137 | 138 | You can search in specific map or in all the memory, `ss` search string in a map, and `sb` search a bunch of bytes hexa separated by hex 139 | 140 | ``` 141 | =>sb 142 | map name=>code 143 | spaced bytes=>24 f4 5f 29 144 | found at 0x3c0009 145 | => 146 | ``` 147 | 148 | If you need to do a search in all the memory `sba` search bytes and `ssa` search strings. 149 | 150 | ## Linked lists 151 | 152 | There is a tool to walk the elements of a linked list which is command `ll` 153 | 154 | ## Dissasemble 155 | 156 | To dissasemble from specific addres use command `d` 157 | 158 | ## SEH and VEH pointers 159 | 160 | The command `seh` allow to see the stack pointer where is the SEH pointers. 161 | 162 | 163 | ``` 164 | =>seh 165 | 0x1b002d 166 | =>mr 167 | memory argument=>dword ptr [0x1b0028] 168 | 0x1b00a7 169 | =>mr 170 | memory argument=>dword ptr [0x1b002c] 171 | 0x3c0012 172 | ``` 173 | 174 | The `veh` return the vectorized exception pointer. 175 | -------------------------------------------------------------------------------- /docs/FIXES.md: -------------------------------------------------------------------------------- 1 | ## Memory overlap 2 | 3 | a bug on the allocator, or in the memory initialization, could cause non determinstic behaviours. 4 | I created a memory test routine launched from console `mt` command, and located the error. 5 | 6 | 7 | -------------------------------------------------------------------------------- /docs/ICED-X86.md: -------------------------------------------------------------------------------- 1 | # Documentation of version 1.15.0 2 | 3 | https://docs.rs/iced-x86/1.15.0/iced_x86/ 4 | 5 | -------------------------------------------------------------------------------- /docs/PROGRAMATICALLY.md: -------------------------------------------------------------------------------- 1 | # Using MWEMU programatically 2 | 3 | just modify the main and implement your custom emulation. 4 | 5 | # normal usage 6 | 7 | The main instatiates emu module, set the config, loads the binary and run. 8 | 9 | 10 | ```rust 11 | let mut emu = Emu::new(); 12 | 13 | emu.set_config(cfg); 14 | emu.init(); 15 | emu.load_code(&filename.to_string()); 16 | 17 | emu.run(0); 18 | ``` 19 | 20 | in run method we can specify a stop address, when emulator reach this address will end the run function. 21 | So we can do multiple runs. 22 | 23 | but run(0) means forever. 24 | 25 | # calling a specific function 26 | 27 | ```rust 28 | 29 | let mut emu = Emu::new(); 30 | 31 | emu.set_config(cfg); 32 | emu.init(); 33 | emu.load_code(&filename.to_string()); 34 | emu.disable_ctrlc(); 35 | 36 | // alloc a buffer needed to generate the key 37 | let buff = emu.alloc("key_buffer", 1024); 38 | 39 | // set eip 40 | emu.regs.set_eip(my_crypto_function_address); // or emu.regs.rip = my_function_address in 64bits 41 | 42 | // params pushed in reverse order 43 | emu.stack_push32(length); 44 | emu.stack_push32(buff); 45 | emu.stack_push32(seed); 46 | emu.stack_push32(0); // return address 47 | 48 | emu.run(ret_address); // stop on latest ret, dont emulate it that will jump to zero. 49 | 50 | // show the buffer in the screen 51 | emu.maps.dump(buff); 52 | 53 | // you can spawn the console if needed 54 | emu.spawn_console(); 55 | ``` 56 | 57 | you can build a program that decrypt stuff by emulating malwares's decryption functions. 58 | 59 | -------------------------------------------------------------------------------- /docs/TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | 4 | - ldr update on LoadLibrary 5 | - implement pe64 6 | - optimize GetProcAddress storing in the handler the lib name 7 | 8 | - support vmprotect 9 | 10 | - set all flags 11 | - list breakpoints 12 | - clear breakpoint bug 13 | - md accept registers 14 | - md memory check the string filter 15 | - mr mw options can crash the console 16 | - fix instruction breakpoint 17 | - more 64bits apis 18 | - in self.execption() put a message self.exception(msg) 19 | - improve seh command 20 | - better api implementations 21 | - winhttp 22 | - implement a basic decompiler in rust. 23 | - remove expect() on implemented instructions, just break; 24 | - stack\_push and stack\_pop assumes the stack is in the memory map stack 25 | - step over 26 | - more fpu and xmm 27 | - on WriteProcessMemory/recv save the payload written to disk 28 | - remove non printable bytes from strings 29 | - randomize initial register for avoid targeted anti-amulation 30 | - support guloader 31 | - scripting 32 | - intead of panic spawn console 33 | - set the code base addr 34 | - on every set\_eip of a non branch dump stack to log file 35 | - other rep instruction preffix 36 | - check pf flag bug 37 | - save state to disk and continue 38 | - command to exit the bucle or to see next instruction 39 | - optimize loop counter 40 | 41 | 42 | - the string change non printables for spaces instead of points: 43 | ``` 44 | =>r rax 45 | rax: 0x3c0037 3932215 'LoadLibraryA ws2_32.dl' (code) 46 | =>s 47 | 0x22dfdc: 0xc () '' 48 | 0x22dfe4: 0x3c0037 (code) 'LoadLibraryA....ws2_32.dll' 49 | ``` 50 | 51 | -------------------------------------------------------------------------------- /libmwemu/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /Cargo.lock 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /libmwemu/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "libmwemu" 3 | version = "0.19.10" 4 | edition = "2018" 5 | authors = ["sha0coder"] 6 | license = "MIT" 7 | description = "x86 32/64bits and system internals emulator, for securely emulating malware and other stuff." 8 | #email = "sha0 at badchecksum.net" 9 | documentation = "https://docs.rs/libmwemu/0.4.15/libmwemu/" 10 | repository = "https://github.com/sha0coder/mwemu" 11 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 12 | 13 | [dependencies] 14 | iced-x86 = { version = "1.21.0", features = ["serde"] } 15 | uint = "0.9.5" 16 | md5 = "0.7.0" 17 | lazy_static = "1.4.0" 18 | rand = "0.9.1" 19 | ctrlc = "3.2.2" 20 | scan_fmt = "0.2.6" 21 | atty = "0.2.14" 22 | csv = "1.3.0" 23 | chrono = { version = "0.4", features = ["serde"] } 24 | log = "0.4.22" 25 | serde = { version = "1.0.217", features = ["derive"] } 26 | bitcode = { version = "0.6.3", features = ["std", "serde"] } 27 | ahash = { version = "0.8.12", features = ["serde"] } 28 | phf = { version = "0.11.3", features = ["macros"]} 29 | 30 | [dev-dependencies] 31 | env_logger = "0.11.8" 32 | 33 | [features] 34 | log_mem = [] 35 | -------------------------------------------------------------------------------- /libmwemu/README.md: -------------------------------------------------------------------------------- 1 | 2 | # MWEMU the lib 3 | 4 | 5 | ## Usage 6 | 7 | Download the maps32 or maps64 from: 8 | https://github.com/sha0coder/mwemu 9 | 10 | In the example it's on /tmp/ but dont use tmp. 11 | 12 | Create an emu32 or emu64 and it's important to set the maps folder. 13 | 14 | ```rust 15 | use libmwemu::emu32; 16 | 17 | 18 | fn main() { 19 | let mut emu = emu32(); 20 | emu.set_maps_folder("/tmp/maps32/"); 21 | emu.init(false, false); 22 | ``` 23 | 24 | Load your shellcode or PE binary and run the emulator. 25 | None parameter means emulate for-ever. 26 | 27 | ```rust 28 | emu.load_code("shellcodes32/shikata.bin"); 29 | emu.set_verbose(2); 30 | emu.run(None).unwrap(); 31 | ``` 32 | 33 | Or if you prefer call specific function. 34 | 35 | ```rust 36 | emu.load_code("samples/malware.exe"); 37 | 38 | let crypto_key_gen = 0x40112233; 39 | let ret_addr = 0x40110000; // any place safe to return. 40 | 41 | let param1 = 0x33; 42 | let param2_out_buff = emu.alloc("buffer", 1024); 43 | 44 | emu.maps.memset(param2_out_buff, 0, 1024); // non necesary, by default alloc create zeros. 45 | emu.maps.write_spaced_bytes(param2_out_buff, 46 | "DE CC 6C 83 CC F3 66 85 34"); // example of initialization. 47 | 48 | // call function 49 | emu.regs.set_eip(crypto_key_gen); 50 | emu.stack_push32(param2_out_buff); 51 | emu.stack_push32(param1); 52 | emu.stack_push32(ret_addr); 53 | emu.run(Some(ret_addr)).unwrap(); // emulate until arrive to ret_addr 54 | 55 | // or simpler way: 56 | let eax = emu.call32(crypto_key_gen, &[param1, param2_out_buff]).unwrap(); 57 | 58 | // this would be slower but more control 59 | while emu.step() { 60 | ... 61 | } 62 | 63 | // check result 64 | log::info!("return value: 0x{:x}", emu.regs.get_eax()); 65 | emu.maps.dump(param2_out_buff); 66 | ``` 67 | 68 | Now it's possible to do hooks on libmwemu but not on pymwemu. 69 | 70 | ```rust 71 | use libmwemu::emu32; 72 | 73 | //need iced_x86 crate only for instruction hooks, to get the 74 | //instruction object, so add `iced-x86 = "1.17.0"` 75 | use iced_x86::{Instruction}; 76 | 77 | 78 | fn trace_memory_read(emu:&mut libmwemu::emu::Emu, ip_addr:u64, 79 | mem_addr:u64, sz:u8) { 80 | log::info!("0x{:x}: reading {} at 0x{:x}", ip_addr, sz, mem_addr); 81 | if mem_addr == 0x22dff0 { 82 | emu.stop(); 83 | } 84 | } 85 | 86 | fn trace_memory_write(emu:&mut libmwemu::emu::Emu, ip_addr:u64, 87 | mem_addr:u64, sz:u8, value:u128) -> u128 { 88 | log::info!("0x{:x}: writing {} '0x{:x}' at 0x{:x}", ip_addr, sz, 89 | value, mem_addr); 90 | value // I could change the value to write 91 | } 92 | 93 | fn trace_interrupt(emu:&mut libmwemu::emu::Emu, ip_addr:u64, 94 | interrupt:u64) -> bool { 95 | log::info!("interrupt {} triggered at eip: 0x{:x}", interrupt, 96 | ip_addr); 97 | true // do handle interrupts 98 | } 99 | 100 | // [BREAKING API CHANGE] a parameter called ex_type with the exception type was added to the hook function. 101 | fn trace_exceptions(emu:&mut libmwemu::emu::Emu, ip_addr:u64, ex_type: libmwemu::exception_type::ExceptionType) -> bool { 102 | log::info!("0x{:x} triggered an exception {}", ip_addr, ex_type); 103 | if (ex_type == libmwemu::exception_type::ExceptionType::Int3) { 104 | // do handle SIGTRAP for example 105 | } 106 | true // do handle exceptions 107 | } 108 | 109 | fn trace_pre_instruction(emu:&mut libmwemu::emu::Emu, ip_addr:u64, 110 | ins:&Instruction, sz:usize) -> bool{ 111 | // return false to skip the instruction 112 | true 113 | } 114 | 115 | fn trace_post_instruction(emu:&mut libmwemu::emu::Emu, ip_addr:u64, 116 | ins:&Instruction, sz:usize, emu_ok:bool) { 117 | } 118 | 119 | fn trace_winapi_call(emu:&mut libmwemu::emu::Emu, ip_addr:u64, api_addr:u64) -> bool { 120 | return true; // handle api calls 121 | } 122 | 123 | fn main() { 124 | let mut emu = emu32(); 125 | emu.set_maps_folder("../mwemu/maps32/"); // download the maps, ideally from mwemu git. 126 | emu.init(); 127 | 128 | emu.load_code("/home/sha0/src/mwemu/shellcodes32/mars.exe"); 129 | emu.hooks.on_memory_read(trace_memory_read); 130 | emu.hooks.on_memory_write(trace_memory_write); 131 | emu.hooks.on_interrupt(trace_interrupt); 132 | emu.hooks.on_exception(trace_exceptions); 133 | emu.hooks.on_pre_instruction(trace_pre_instruction); 134 | emu.hooks.on_post_instruction(trace_post_instruction); 135 | emu.hooks.on_winapi_call(trace_winapi_call); 136 | emu.run(None).unwrap(); 137 | log::info!("end!"); 138 | } 139 | ``` 140 | -------------------------------------------------------------------------------- /libmwemu/src/breakpoint.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Clone, Serialize, Deserialize)] 4 | pub struct Breakpoint { 5 | addr: u64, 6 | instruction: u64, 7 | mem_read_addr: u64, 8 | mem_write_addr: u64, 9 | } 10 | 11 | impl Default for Breakpoint { 12 | fn default() -> Self { 13 | Self::new() 14 | } 15 | } 16 | 17 | impl Breakpoint { 18 | pub fn new() -> Breakpoint { 19 | Breakpoint { 20 | addr: 0, 21 | instruction: 0, 22 | mem_read_addr: 0, 23 | mem_write_addr: 0, 24 | } 25 | } 26 | 27 | pub fn set_bp(&mut self, addr: u64) { 28 | self.addr = addr; 29 | } 30 | 31 | pub fn clear_bp(&mut self) { 32 | self.addr = 0; 33 | self.mem_read_addr = 0; 34 | self.mem_write_addr = 0; 35 | } 36 | 37 | pub fn set_mem_read(&mut self, addr: u64) { 38 | self.mem_read_addr = addr; 39 | } 40 | 41 | pub fn set_mem_write(&mut self, addr: u64) { 42 | self.mem_write_addr = addr; 43 | } 44 | 45 | pub fn set_instruction(&mut self, ins: u64) { 46 | self.instruction = ins; 47 | } 48 | 49 | pub fn get_bp(&self) -> u64 { 50 | self.addr 51 | } 52 | 53 | pub fn get_mem_read(&self) -> u64 { 54 | self.mem_read_addr 55 | } 56 | 57 | pub fn get_mem_write(&self) -> u64 { 58 | self.mem_write_addr 59 | } 60 | 61 | pub fn get_instruction(&self) -> u64 { 62 | self.instruction 63 | } 64 | 65 | pub fn show(&self) { 66 | log::info!("break on address: 0x{:x}", self.addr); 67 | log::info!("break on instruction: {}", self.instruction); 68 | log::info!("break on memory read: 0x{:x}", self.mem_read_addr); 69 | log::info!("break on memory write: 0x{:x}", self.mem_write_addr); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /libmwemu/src/colors.rs: -------------------------------------------------------------------------------- 1 | // TODO: move these to const? 2 | 3 | use serde::{Deserialize, Serialize}; 4 | 5 | #[derive(Clone, Serialize, Deserialize)] 6 | pub struct Colors { 7 | pub black: String, 8 | pub red: String, 9 | pub green: String, 10 | pub orange: String, 11 | pub blue: String, 12 | pub purple: String, 13 | pub cyan: String, 14 | pub light_gray: String, 15 | pub dark_gray: String, 16 | pub light_red: String, 17 | pub light_green: String, 18 | pub yellow: String, 19 | pub light_blue: String, 20 | pub light_purple: String, 21 | pub light_cyan: String, 22 | pub white: String, 23 | pub nc: String, // no_color 24 | pub clear_screen: String, 25 | } 26 | 27 | impl Default for Colors { 28 | fn default() -> Self { 29 | Self::new() 30 | } 31 | } 32 | 33 | impl Colors { 34 | pub fn new() -> Colors { 35 | Colors { 36 | black: "\x1b[0;30m".to_string(), 37 | red: "\x1b[0;31m".to_string(), 38 | green: "\x1b[0;32m".to_string(), 39 | orange: "\x1b[0;33m".to_string(), 40 | blue: "\x1b[0;34m".to_string(), 41 | purple: "\x1b[0;35m".to_string(), 42 | cyan: "\x1b[0;36m".to_string(), 43 | light_gray: "\x1b[0;37m".to_string(), 44 | dark_gray: "\x1b[1;30m".to_string(), 45 | light_red: "\x1b[1;31m".to_string(), 46 | light_green: "\x1b[1;32m".to_string(), 47 | yellow: "\x1b[1;33m".to_string(), 48 | light_blue: "\x1b[1;34m".to_string(), 49 | light_purple: "\x1b[1;35m".to_string(), 50 | light_cyan: "\x1b[1;36m".to_string(), 51 | white: "\x1b[1;37m".to_string(), 52 | nc: "\x1b[0m".to_string(), // no_color 53 | clear_screen: "\x1bc".to_string(), 54 | } 55 | } 56 | 57 | pub fn disable(&mut self) { 58 | self.black = "".to_string(); 59 | self.red = "".to_string(); 60 | self.green = "".to_string(); 61 | self.orange = "".to_string(); 62 | self.blue = "".to_string(); 63 | self.purple = "".to_string(); 64 | self.cyan = "".to_string(); 65 | self.light_gray = "".to_string(); 66 | self.dark_gray = "".to_string(); 67 | self.light_red = "".to_string(); 68 | self.light_green = "".to_string(); 69 | self.yellow = "".to_string(); 70 | self.light_blue = "".to_string(); 71 | self.light_purple = "".to_string(); 72 | self.light_cyan = "".to_string(); 73 | self.white = "".to_string(); 74 | self.nc = "".to_string(); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /libmwemu/src/config.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Clone, Serialize, Deserialize)] 4 | pub struct Config { 5 | pub filename: String, // filename with full path included 6 | pub trace_mem: bool, // show memory operations in every step. 7 | pub trace_regs: bool, // show all the regs in every step. 8 | pub trace_reg: bool, // show value and content of a reg in every step. 9 | pub trace_filename: Option, 10 | pub trace_start: u64, 11 | pub reg_names: Vec, // which reg to trace. 12 | pub verbose: u32, // 0 only view the api, 1 api + messages, 2 asm code. 13 | pub console: bool, // enable the console on specific moment?. 14 | pub console_num: u64, // in which moment enable the console. 15 | pub loops: bool, // loop mode count the iterations for every instruction, its slow. 16 | pub nocolors: bool, // to redirecting the output to a file is better to remove colors. 17 | pub trace_string: bool, 18 | pub string_addr: u64, 19 | pub inspect: bool, 20 | pub inspect_seq: String, 21 | pub endpoint: bool, 22 | pub maps_folder: String, 23 | pub console2: bool, 24 | pub console_addr: u64, 25 | pub entry_point: u64, 26 | pub exit_position: u64, 27 | pub dump_on_exit: bool, 28 | pub dump_filename: Option, 29 | pub code_base_addr: u64, 30 | pub is_64bits: bool, // 64bits mode 31 | pub stack_trace: bool, 32 | pub test_mode: bool, 33 | pub console_enabled: bool, 34 | pub skip_unimplemented: bool, 35 | pub stack_addr: u64, 36 | } 37 | 38 | impl Default for Config { 39 | fn default() -> Self { 40 | Self::new() 41 | } 42 | } 43 | 44 | impl Config { 45 | pub fn new() -> Config { 46 | Config { 47 | filename: String::new(), 48 | trace_mem: false, 49 | trace_regs: false, 50 | trace_reg: false, 51 | trace_filename: None, 52 | trace_start: 0, 53 | reg_names: Vec::new(), 54 | verbose: 0, 55 | console: false, 56 | console_num: 0, 57 | loops: false, 58 | nocolors: false, 59 | trace_string: false, 60 | string_addr: 0, 61 | inspect: false, 62 | inspect_seq: "".to_string(), 63 | endpoint: false, 64 | maps_folder: "".to_string(), 65 | console2: false, 66 | console_addr: 0, 67 | entry_point: 0x3c0000, 68 | exit_position: 0, 69 | dump_on_exit: true, // TODO: a way to make it false/set it through cli + lib 70 | dump_filename: Some("dumps/emu.bin".to_string()), // TODO: a way to set it through cli + lib 71 | code_base_addr: 0x3c0000, 72 | is_64bits: false, 73 | stack_trace: false, 74 | test_mode: false, 75 | console_enabled: true, 76 | skip_unimplemented: false, 77 | stack_addr: 0, 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /libmwemu/src/context32.rs: -------------------------------------------------------------------------------- 1 | use crate::fpu::FPU; 2 | use crate::maps::Maps; 3 | use crate::regs64::Regs64; 4 | 5 | pub struct Context32 { 6 | ctx_flags: u32, 7 | dr0: u32, 8 | dr1: u32, 9 | dr2: u32, 10 | dr3: u32, 11 | dr6: u32, 12 | dr7: u32, 13 | fpu: FPU, 14 | seg_gs: u32, 15 | seg_fd: u32, 16 | seg_es: u32, 17 | seg_ds: u32, 18 | edi: u32, // +9c 19 | esi: u32, // +a0 20 | ebx: u32, // +a4 21 | edx: u32, // +a8 22 | ecx: u32, // +ac 23 | eax: u32, // +b0 24 | ebp: u32, // +b4 25 | eip: u32, // +b8 26 | seg_cs: u32, // +bc 27 | eflags: u32, // +c0 28 | esp: u32, // +c4 29 | seg_ss: u32, 30 | } 31 | 32 | impl Context32 { 33 | pub fn new(regs: &Regs64) -> Context32 { 34 | Context32 { 35 | ctx_flags: 0, 36 | dr0: 0, 37 | dr1: 0, 38 | dr2: 0, 39 | dr3: 0, 40 | dr6: 0, 41 | dr7: 0, 42 | fpu: FPU::new(), 43 | seg_gs: 0, 44 | seg_fd: 0, 45 | seg_es: 0, 46 | seg_ds: 0, 47 | edi: regs.get_edi() as u32, 48 | esi: regs.get_esi() as u32, 49 | ebx: regs.get_ebx() as u32, 50 | edx: regs.get_edx() as u32, 51 | ecx: regs.get_ecx() as u32, 52 | eax: regs.get_eax() as u32, 53 | ebp: regs.get_ebp() as u32, 54 | eip: regs.get_eip() as u32, 55 | seg_cs: 0, 56 | eflags: 0, 57 | esp: regs.get_esp() as u32, 58 | seg_ss: 0, 59 | } 60 | } 61 | 62 | pub fn save(&self, addr: u32, maps: &mut Maps) { 63 | maps.write_dword((addr + 4) as u64, self.dr0); 64 | maps.write_dword((addr + 8) as u64, self.dr1); 65 | maps.write_dword((addr + 12) as u64, self.dr2); 66 | maps.write_dword((addr + 16) as u64, self.dr3); 67 | maps.write_dword((addr + 20) as u64, self.dr6); 68 | maps.write_dword((addr + 24) as u64, self.dr7); 69 | 70 | maps.write_dword((addr + 0x9c) as u64, self.edi); 71 | maps.write_dword((addr + 0xa0) as u64, self.esi); 72 | maps.write_dword((addr + 0xa4) as u64, self.ebx); 73 | maps.write_dword((addr + 0xa8) as u64, self.edx); 74 | maps.write_dword((addr + 0xac) as u64, self.ecx); 75 | maps.write_dword((addr + 0xb0) as u64, self.eax); 76 | maps.write_dword((addr + 0xb4) as u64, self.ebp); 77 | maps.write_dword((addr + 0xb8) as u64, self.eip); 78 | maps.write_dword((addr + 0xc4) as u64, self.esp); 79 | } 80 | 81 | pub fn load(&mut self, addr: u32, maps: &mut Maps) { 82 | self.dr0 = maps 83 | .read_dword((addr + 4) as u64) 84 | .expect("cannot read dr0 from ctx"); 85 | self.dr1 = maps 86 | .read_dword((addr + 8) as u64) 87 | .expect("cannot read dr1 from ctx"); 88 | self.dr2 = maps 89 | .read_dword((addr + 12) as u64) 90 | .expect("cannot read dr2 from ctx"); 91 | self.dr3 = maps 92 | .read_dword((addr + 16) as u64) 93 | .expect("cannot read dr3 from ctx"); 94 | self.dr6 = maps 95 | .read_dword((addr + 20) as u64) 96 | .expect("cannot read dr6 from ctx"); 97 | self.dr7 = maps 98 | .read_dword((addr + 24) as u64) 99 | .expect("cannot read dr7 from ctx"); 100 | 101 | self.edi = maps 102 | .read_dword((addr + 0x9c) as u64) 103 | .expect("cannot read edi from ctx"); 104 | self.esi = maps 105 | .read_dword((addr + 0xa0) as u64) 106 | .expect("cannot read esi from ctx"); 107 | self.ebx = maps 108 | .read_dword((addr + 0xa4) as u64) 109 | .expect("cannot read ebx from ctx"); 110 | self.edx = maps 111 | .read_dword((addr + 0xa8) as u64) 112 | .expect("cannot read edx from ctx"); 113 | self.ecx = maps 114 | .read_dword((addr + 0xac) as u64) 115 | .expect("cannot read ecx from ctx"); 116 | self.eax = maps 117 | .read_dword((addr + 0xb0) as u64) 118 | .expect("cannot read eax from ctx"); 119 | self.ebp = maps 120 | .read_dword((addr + 0xb4) as u64) 121 | .expect("cannot read ebp from ctx"); 122 | self.eip = maps 123 | .read_dword((addr + 0xb8) as u64) 124 | .expect("cannot read eip from ctx"); 125 | self.esp = maps 126 | .read_dword((addr + 0xc4) as u64) 127 | .expect("cannot read esp from ctx"); 128 | } 129 | 130 | pub fn sync(&self, regs: &mut Regs64) { 131 | regs.set_eax(self.eax as u64); 132 | regs.set_ebx(self.ebx as u64); 133 | regs.set_ecx(self.ecx as u64); 134 | regs.set_edx(self.edx as u64); 135 | regs.set_esi(self.esi as u64); 136 | regs.set_edi(self.edi as u64); 137 | regs.set_esp(self.esp as u64); 138 | regs.set_ebp(self.ebp as u64); 139 | regs.set_eip(self.eip as u64); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /libmwemu/src/eflags.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Clone, Serialize, Deserialize)] 4 | pub struct Eflags { 5 | pub rf: bool, 6 | pub vm: bool, 7 | pub ac: bool, 8 | pub vif: bool, 9 | pub id: bool, 10 | } 11 | 12 | impl Default for Eflags { 13 | fn default() -> Self { 14 | Self::new() 15 | } 16 | } 17 | 18 | impl Eflags { 19 | pub fn new() -> Eflags { 20 | Eflags { 21 | rf: false, 22 | vm: false, 23 | ac: false, 24 | vif: false, 25 | id: false, 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /libmwemu/src/err.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error; 2 | 3 | #[derive(Debug)] 4 | pub struct MwemuError { 5 | pub message: String, 6 | } 7 | 8 | impl MwemuError { 9 | pub fn new(message: &str) -> MwemuError { 10 | MwemuError { 11 | message: message.to_string(), 12 | } 13 | } 14 | } 15 | 16 | impl std::fmt::Display for MwemuError { 17 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 18 | write!(f, "MWEMU Error: {}", self.message) 19 | } 20 | } 21 | 22 | impl Error for MwemuError {} 23 | -------------------------------------------------------------------------------- /libmwemu/src/exception.rs: -------------------------------------------------------------------------------- 1 | use crate::context32::Context32; 2 | use crate::context64::Context64; 3 | use crate::emu; 4 | 5 | pub fn enter(emu: &mut emu::Emu) { 6 | if emu.cfg.is_64bits { 7 | enter64(emu); 8 | } else { 9 | enter32(emu); 10 | } 11 | } 12 | 13 | pub fn exit(emu: &mut emu::Emu) { 14 | if emu.cfg.is_64bits { 15 | exit64(emu); 16 | } else { 17 | exit32(emu); 18 | } 19 | } 20 | 21 | pub fn enter32(emu: &mut emu::Emu) { 22 | emu.stack_push32(0x10f00); 23 | emu.stack_push32(emu.regs.get_eip() as u32); 24 | 25 | emu.eh_ctx = 0x10f08; 26 | emu.maps.write_dword(0x10f04, emu.eh_ctx); 27 | let ctx = Context32::new(&emu.regs); 28 | ctx.save(emu.eh_ctx, &mut emu.maps); 29 | } 30 | 31 | pub fn exit32(emu: &mut emu::Emu) { 32 | let mut ctx = Context32::new(&emu.regs); 33 | ctx.load(emu.eh_ctx, &mut emu.maps); 34 | ctx.sync(&mut emu.regs); 35 | emu.eh_ctx = 0; 36 | emu.force_reload = true; 37 | } 38 | 39 | pub fn enter64(emu: &mut emu::Emu) { 40 | emu.stack_push64(0x10f00); 41 | emu.stack_push64(emu.regs.rip); 42 | 43 | emu.eh_ctx = 0x10f08; 44 | emu.maps.write_qword(0x10f04, emu.eh_ctx as u64); 45 | let ctx = Context64::new(&emu.regs); 46 | ctx.save(emu.eh_ctx as u64, &mut emu.maps); 47 | } 48 | 49 | pub fn exit64(emu: &mut emu::Emu) { 50 | let mut ctx = Context64::new(&emu.regs); 51 | ctx.load(emu.eh_ctx as u64, &mut emu.maps); 52 | ctx.sync(&mut emu.regs); 53 | emu.eh_ctx = 0; 54 | emu.force_reload = true; 55 | } 56 | -------------------------------------------------------------------------------- /libmwemu/src/exception_type.rs: -------------------------------------------------------------------------------- 1 | #[derive(Clone, Copy)] 2 | pub enum ExceptionType { 3 | Int3, // int 3 breakpoint 4 | Div0, // division by zero 5 | SignChangeOnDivision, // sign change exception on division 6 | PopfCannotReadStack, // popf cannot read stack 7 | WritingWord, // exception writing word 8 | SettingRipToNonMappedAddr, // setting rip to non mapped addr 9 | QWordDereferencing, // error dereferencing qword 10 | DWordDereferencing, // error dereferencing dword 11 | WordDereferencing, // error dereferencing word 12 | ByteDereferencing, // error dereferencing byte 13 | BadAddressDereferencing, // exception dereferencing bad address 14 | SettingXmmOperand, // exception setting xmm operand 15 | ReadingXmmOperand, // exception reading xmm operand 16 | } 17 | 18 | impl PartialEq for ExceptionType { 19 | fn eq(&self, other: &Self) -> bool { 20 | return *self as u32 == *other as u32; 21 | } 22 | } 23 | 24 | impl std::fmt::Display for ExceptionType { 25 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 26 | match self { 27 | ExceptionType::Int3 => write!(f, "int 3"), 28 | ExceptionType::Div0 => write!(f, "division by zero"), 29 | ExceptionType::SignChangeOnDivision => write!(f, "sign change exception on division"), 30 | ExceptionType::PopfCannotReadStack => write!(f, "popf cannot read stack"), 31 | ExceptionType::WritingWord => write!(f, "exception writing word"), 32 | ExceptionType::SettingRipToNonMappedAddr => write!(f, "setting rip to non mapped addr"), 33 | ExceptionType::QWordDereferencing => write!(f, "error dereferencing qword"), 34 | ExceptionType::DWordDereferencing => write!(f, "error dereferencing dword"), 35 | ExceptionType::WordDereferencing => write!(f, "error dereferencing word"), 36 | ExceptionType::ByteDereferencing => write!(f, "error dereferencing byte"), 37 | ExceptionType::BadAddressDereferencing => { 38 | write!(f, "exception dereferencing bad address") 39 | } 40 | ExceptionType::SettingXmmOperand => write!(f, "exception setting xmm operand"), 41 | ExceptionType::ReadingXmmOperand => write!(f, "exception reading xmm operand"), 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /libmwemu/src/hooks.rs: -------------------------------------------------------------------------------- 1 | use iced_x86::Instruction; 2 | 3 | use crate::emu; 4 | use crate::exception_type; 5 | 6 | // return: false will ignore interrupt handling like 0x80 -> linux 7 | type TypeHookOnInterrupt = fn(emu: &mut emu::Emu, ip_addr: u64, interrupt: u64) -> bool; 8 | // return: allow handle exception? 9 | type TypeHookOnException = 10 | fn(emu: &mut emu::Emu, ip_addr: u64, ex_type: exception_type::ExceptionType) -> bool; 11 | // memory read is pre-read you can modify the value that is going to be read. 12 | type TypeHookOnMemoryRead = fn(emu: &mut emu::Emu, ip_addr: u64, mem_addr: u64, sz: u32); 13 | // the memory write is pre but you can change the value is going to be written. 14 | type TypeHookOnMemoryWrite = 15 | fn(emu: &mut emu::Emu, ip_addr: u64, mem_addr: u64, sz: u32, value: u128) -> u128; 16 | 17 | // [BREAKING API CHANGE] returning false will skip the handling of the instruction 18 | type TypeHookOnPreInstruction = 19 | fn(emu: &mut emu::Emu, ip_addr: u64, ins: &Instruction, sz: usize) -> bool; 20 | 21 | type TypeHookOnPostInstruction = 22 | fn(emu: &mut emu::Emu, ip_addr: u64, ins: &Instruction, sz: usize, emu_ok: bool); 23 | type TypeHookOnWinApiCall = fn(emu: &mut emu::Emu, ip_addr: u64, called_addr: u64) -> bool; 24 | 25 | pub struct Hooks { 26 | pub hook_on_interrupt: Option, 27 | pub hook_on_exception: Option, 28 | pub hook_on_memory_read: Option, 29 | pub hook_on_memory_write: Option, 30 | pub hook_on_pre_instruction: Option, 31 | pub hook_on_post_instruction: Option, 32 | pub hook_on_winapi_call: Option, 33 | } 34 | 35 | impl Default for Hooks { 36 | fn default() -> Self { 37 | Self::new() 38 | } 39 | } 40 | 41 | impl Hooks { 42 | pub fn new() -> Hooks { 43 | Hooks { 44 | hook_on_interrupt: None, 45 | hook_on_exception: None, 46 | hook_on_memory_read: None, 47 | hook_on_memory_write: None, 48 | hook_on_pre_instruction: None, 49 | hook_on_post_instruction: None, 50 | hook_on_winapi_call: None, 51 | } 52 | } 53 | 54 | pub fn on_interrupt(&mut self, hook: TypeHookOnInterrupt) { 55 | self.hook_on_interrupt = Some(hook); 56 | } 57 | 58 | pub fn disable_interrupt(&mut self) { 59 | self.hook_on_interrupt = None; 60 | } 61 | 62 | pub fn on_exception(&mut self, hook: TypeHookOnException) { 63 | self.hook_on_exception = Some(hook); 64 | } 65 | 66 | pub fn disable_exception(&mut self) { 67 | self.hook_on_exception = None; 68 | } 69 | 70 | pub fn on_memory_read(&mut self, hook: TypeHookOnMemoryRead) { 71 | self.hook_on_memory_read = Some(hook); 72 | } 73 | 74 | pub fn disable_memory_read(&mut self) { 75 | self.hook_on_memory_read = None; 76 | } 77 | 78 | pub fn on_memory_write(&mut self, hook: TypeHookOnMemoryWrite) { 79 | self.hook_on_memory_write = Some(hook); 80 | } 81 | 82 | pub fn disable_memory_write(&mut self) { 83 | self.hook_on_memory_write = None; 84 | } 85 | 86 | pub fn on_pre_instruction(&mut self, hook: TypeHookOnPreInstruction) { 87 | self.hook_on_pre_instruction = Some(hook); 88 | } 89 | 90 | pub fn disable_pre_instruction(&mut self) { 91 | self.hook_on_pre_instruction = None; 92 | } 93 | 94 | pub fn on_post_instruction(&mut self, hook: TypeHookOnPostInstruction) { 95 | self.hook_on_post_instruction = Some(hook); 96 | } 97 | 98 | pub fn disable_post_instruction(&mut self) { 99 | self.hook_on_post_instruction = None; 100 | } 101 | 102 | pub fn on_winapi_call(&mut self, hook: TypeHookOnWinApiCall) { 103 | self.hook_on_winapi_call = Some(hook); 104 | } 105 | 106 | pub fn disable_winapi_call(&mut self) { 107 | self.hook_on_winapi_call = None; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /libmwemu/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(non_snake_case)] 2 | #![allow(dead_code)] 3 | #![allow(unused_variables)] 4 | #![allow(unused_must_use)] 5 | #![allow(clippy::assertions_on_constants)] 6 | 7 | pub mod banzai; 8 | pub mod breakpoint; 9 | pub mod colors; 10 | pub mod config; 11 | pub mod console; 12 | pub mod constants; 13 | pub mod context32; 14 | pub mod context64; 15 | pub mod eflags; 16 | pub mod elf32; 17 | pub mod elf64; 18 | pub mod emu; 19 | //pub mod endpoint; 20 | pub mod engine; 21 | pub mod err; 22 | pub mod exception; 23 | pub mod flags; 24 | pub mod fpu; 25 | pub mod hooks; 26 | pub mod inline; 27 | #[macro_use] 28 | pub mod macros; 29 | pub mod exception_type; 30 | pub mod maps; 31 | pub mod ntapi32; 32 | pub mod pe32; 33 | pub mod pe64; 34 | pub mod peb32; 35 | pub mod peb64; 36 | pub mod regs64; 37 | pub mod script; 38 | pub mod serialization; 39 | pub mod structures; 40 | pub mod syscall32; 41 | pub mod syscall64; 42 | pub mod winapi32; 43 | pub mod winapi64; 44 | 45 | #[cfg(test)] 46 | mod tests; 47 | 48 | use config::Config; 49 | use emu::Emu; 50 | 51 | pub fn emu64() -> Emu { 52 | let mut emu = Emu::new(); 53 | let mut cfg = Config::new(); 54 | cfg.is_64bits = true; 55 | emu.set_config(cfg); 56 | emu.disable_ctrlc(); 57 | 58 | emu 59 | } 60 | 61 | pub fn emu32() -> Emu { 62 | let mut emu = Emu::new(); 63 | let mut cfg = Config::new(); 64 | cfg.is_64bits = false; 65 | emu.set_config(cfg); 66 | emu.disable_ctrlc(); 67 | 68 | emu 69 | } 70 | -------------------------------------------------------------------------------- /libmwemu/src/macros.rs: -------------------------------------------------------------------------------- 1 | /*macro_rules! stack_param { 2 | ($emu:expr, $num:expr, $msg:expr) => ( 3 | $emu.read_dword($emu.regs.esp+($num*4)).expect($msg); 4 | ) 5 | } 6 | 7 | macro_rules! get_ip { 8 | ($emu:expr, $ptr:expr) => ( 9 | let ip = $emu.maps.read_dword($ptr+4).expect("cannot read the ip"); 10 | format!("{}.{}.{}.{}", ip&0xff, (ip&0xff00)>>8, (ip&0xff0000)>>16, (ip&0xff000000)>>24); 11 | ) 12 | } 13 | 14 | macro_rules! read_u8 { 15 | ($raw:expr, $off:expr) => { 16 | $raw[$off] 17 | }; 18 | } 19 | 20 | macro_rules! read_u16_le { 21 | ($raw:expr, $off:expr) => { 22 | (($raw[$off + 1] as u16) << 8) | ($raw[$off] as u16) 23 | }; 24 | } 25 | 26 | macro_rules! read_u32_le { 27 | ($raw:expr, $off:expr) => { 28 | (($raw[$off + 3] as u32) << 24) 29 | | (($raw[$off + 2] as u32) << 16) 30 | | (($raw[$off + 1] as u32) << 8) 31 | | ($raw[$off] as u32) 32 | }; 33 | } 34 | 35 | macro_rules! write_u32_le { 36 | ($raw:expr, $off:expr, $val:expr) => { 37 | $raw[$off + 0] = ($val & 0x000000ff) as u8; 38 | $raw[$off + 1] = (($val & 0x0000ff00) >> 8) as u8; 39 | $raw[$off + 2] = (($val & 0x00ff0000) >> 16) as u8; 40 | $raw[$off + 3] = (($val & 0xff000000) >> 24) as u8; 41 | }; 42 | } 43 | 44 | macro_rules! read_u64_le { 45 | ($raw:expr, $off:expr) => { 46 | (($raw[$off + 7] as u64) << 56) 47 | | (($raw[$off + 6] as u64) << 48) 48 | | (($raw[$off + 5] as u64) << 40) 49 | | (($raw[$off + 4] as u64) << 32) 50 | | (($raw[$off + 3] as u64) << 24) 51 | | (($raw[$off + 2] as u64) << 16) 52 | | (($raw[$off + 1] as u64) << 8) 53 | | ($raw[$off] as u64) 54 | }; 55 | } 56 | 57 | macro_rules! write_u64_le { 58 | ($raw:expr, $off:expr, $val:expr) => { 59 | $raw[$off+0] = ($val & 0x00000000_000000ff) as u8; 60 | $raw[$off+1] = (($val & 0x00000000_0000ff00) >> 8) as u8; 61 | $raw[$off+2] = (($val & 0x00000000_00ff0000) >> 16) as u8; 62 | $raw[$off+3] = (($val & 0x00000000_ff000000) >> 24) as u8; 63 | $raw[$off+4] = (($val & 0x000000ff_00000000) >> 32) as u8; 64 | $raw[$off+5] = (($val & 0x0000ff00_00000000) >> 40) as u8; 65 | $raw[$off+6] = (($val & 0x00ff0000_00000000) >> 48) as u8; 66 | $raw[$off+7] = (($val & 0xff000000_00000000) >> 56) as u8; 67 | } 68 | } 69 | 70 | macro_rules! rotate_left { 71 | ($val:expr, $rot:expr, $bits:expr) => { 72 | ($val << $rot) | ($val >> ($bits-$rot)) 73 | }; 74 | } 75 | 76 | macro_rules! rotate_right { 77 | ($val:expr, $rot:expr, $bits:expr) => { 78 | ($val >> $rot) | ($val << ($bits-$rot)) 79 | }; 80 | }*/ 81 | 82 | #[macro_export] 83 | macro_rules! popn { 84 | ($emu:expr, $n:expr) => { 85 | for _ in 0..$n { 86 | $emu.stack_pop(false); 87 | } 88 | }; 89 | } 90 | 91 | #[macro_export] 92 | macro_rules! get_bit { 93 | ($val:expr, $count:expr) => { 94 | ($val & (1 << $count)) >> $count 95 | }; 96 | } 97 | 98 | #[macro_export] 99 | macro_rules! set_bit { 100 | ($val:expr, $count:expr, $bit:expr) => { 101 | if $bit == 1 { 102 | $val |= 1 << $count; 103 | } else { 104 | $val &= !(1 << $count); 105 | } 106 | }; 107 | } 108 | 109 | #[macro_export] 110 | macro_rules! to32 { 111 | ($val:expr) => { 112 | ($val & 0xffffffff) as u32 113 | }; 114 | } 115 | 116 | #[macro_export] 117 | macro_rules! log_red { 118 | ($emu:expr, $($arg:tt)*) => { 119 | log::info!( 120 | "{}{}{}", 121 | $emu.colors.light_red, 122 | format!($($arg)*), 123 | $emu.colors.nc 124 | ); 125 | }; 126 | } 127 | -------------------------------------------------------------------------------- /libmwemu/src/ntapi32.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use iced_x86::Formatter; 3 | /* 4 | use crate::console; 5 | use crate::constants; 6 | use crate::context32; 7 | use crate::peb32; 8 | use crate::structures; 9 | use lazy_static::lazy_static; 10 | use std::sync::Mutex; 11 | */ 12 | 13 | pub fn gateway(syscall: u64, argv: u64, emu: &mut emu::Emu) { 14 | match syscall { 15 | 0xdc => { 16 | log::info!("/!\\ direct syscall: NtAlpcSendWaitReceivePort"); 17 | emu.regs.rax = 0; 18 | } 19 | 20 | 0x10f => { 21 | log::info!("/!\\ direct syscall: NtOpenFile {:x}", argv); 22 | emu.regs.rax = 0; 23 | } 24 | 25 | _ => { 26 | let mut output = String::new(); 27 | emu.formatter.format(&emu.instruction.unwrap(), &mut output); 28 | log::info!( 29 | "{}{} 0x{:x}: {}{}", 30 | emu.colors.red, 31 | emu.pos, 32 | emu.regs.rip, 33 | output, 34 | emu.colors.nc 35 | ); 36 | unimplemented!(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /libmwemu/src/tests.rs: -------------------------------------------------------------------------------- 1 | // cargo test -- --nocapture 2 | 3 | #[cfg(test)] 4 | mod tests { 5 | use std::io::Write as _; 6 | use std::sync::Once; 7 | 8 | use crate::emu::Emu; 9 | use crate::emu64; 10 | use crate::serialization::Serialization; 11 | 12 | static INIT: Once = Once::new(); 13 | 14 | fn setup() { 15 | INIT.call_once(|| { 16 | env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")) 17 | .format(|buf, record| writeln!(buf, "{}", record.args())) 18 | .init(); 19 | }); 20 | } 21 | 22 | #[test] 23 | #[ignore] 24 | fn should_serialize() { 25 | setup(); 26 | 27 | // init 28 | let mut emu = emu64(); 29 | 30 | // load maps 31 | emu.cfg.maps_folder = "../maps64/".to_string(); 32 | emu.init(false, false); 33 | 34 | // load binary 35 | let filename = format!( 36 | "/Users/{username}/Desktop/enigma/surprise.dll", 37 | username = std::env::var("USER").unwrap() 38 | ); 39 | emu.load_code(&filename); 40 | 41 | // set registers 42 | emu.regs.rdx = 0x1; 43 | 44 | // serialize 45 | let serialized = Serialization::serialize(&emu); 46 | 47 | // deserialize 48 | let emu: Emu = Serialization::deserialize(&serialized); 49 | 50 | // assert 51 | assert_eq!(emu.regs.rdx, 0x1); 52 | } 53 | 54 | #[test] 55 | #[ignore] 56 | fn should_run() { 57 | setup(); 58 | 59 | // init 60 | let mut emu = emu64(); 61 | 62 | // load maps 63 | emu.cfg.maps_folder = "../maps64/".to_string(); 64 | emu.init(false, false); 65 | 66 | // load binary 67 | let filename = format!( 68 | "/Users/{username}/Desktop/enigma/surprise.dll", 69 | username = std::env::var("USER").unwrap() 70 | ); 71 | emu.load_code(&filename); 72 | 73 | // set registers 74 | emu.regs.rdx = 0x1; 75 | 76 | // set exit position 77 | emu.cfg.exit_position = 100; 78 | 79 | // run 80 | let exit_addr = None; 81 | emu.run(exit_addr); 82 | 83 | // assert 84 | assert_eq!(emu.regs.rdx, 0x7FFFFFFFFFFFFFFF); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /libmwemu/src/winapi32/crypt32.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi32::kernel32; 4 | /* 5 | use crate::winapi32::helper; 6 | use crate::context32; 7 | use crate::constants; 8 | use crate::console; 9 | */ 10 | 11 | pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String { 12 | let api = kernel32::guess_api_name(emu, addr); 13 | match api.as_str() { 14 | "PkiInitializeCriticalSection" => PkiInitializeCriticalSection(emu), 15 | "CryptStringToBinaryA" => CryptStringToBinaryA(emu), 16 | 17 | _ => { 18 | if emu.cfg.skip_unimplemented == false { 19 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 20 | serialization::Serialization::dump_to_file( 21 | &emu, 22 | emu.cfg.dump_filename.as_ref().unwrap(), 23 | ); 24 | } 25 | 26 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 27 | } 28 | log::warn!( 29 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 30 | addr, 31 | api, 32 | emu.regs.rip 33 | ); 34 | return api; 35 | } 36 | } 37 | 38 | String::new() 39 | } 40 | 41 | fn PkiInitializeCriticalSection(emu: &mut emu::Emu) { 42 | let addr = emu 43 | .maps 44 | .read_dword(emu.regs.get_esp()) 45 | .expect("crypt32!PkiInitializeCriticalSection error getting flags param"); 46 | let flags = emu 47 | .maps 48 | .read_dword(emu.regs.get_esp() + 4) 49 | .expect("crypt32!PkiInitializeCriticalSection error getting addr param"); 50 | 51 | log::info!( 52 | "{}** {} crypt32!Pki_InitializeCriticalSection flags: {:x} addr: 0x{:x} {}", 53 | emu.colors.light_red, 54 | emu.pos, 55 | flags, 56 | addr, 57 | emu.colors.nc 58 | ); 59 | 60 | for _ in 0..2 { 61 | emu.stack_pop32(false); 62 | } 63 | emu.regs.rax = 1; 64 | } 65 | 66 | fn CryptStringToBinaryA(emu: &mut emu::Emu) { 67 | let string = emu 68 | .maps 69 | .read_dword(emu.regs.get_esp()) 70 | .expect("crypt32!CryptStringToBinaryA error getting flags param"); 71 | let num_chars = emu 72 | .maps 73 | .read_dword(emu.regs.get_esp() + 4) 74 | .expect("crypt32!PCryptStringToBinaryA error getting addr param"); 75 | let flags = emu 76 | .maps 77 | .read_dword(emu.regs.get_esp() + 8) 78 | .expect("crypt32!CryptStringToBinaryA error getting flags param"); 79 | let ptr = emu 80 | .maps 81 | .read_dword(emu.regs.get_esp() + 12) 82 | .expect("crypt32!PCryptStringToBinaryA error getting addr param"); 83 | let inout_sz = emu 84 | .maps 85 | .read_dword(emu.regs.get_esp() + 16) 86 | .expect("crypt32!CryptStringToBinaryA error getting flags param"); 87 | let skip = emu 88 | .maps 89 | .read_dword(emu.regs.get_esp() + 20) 90 | .expect("crypt32!PCryptStringToBinaryA error getting addr param"); 91 | let out_flags = emu 92 | .maps 93 | .read_dword(emu.regs.get_esp() + 24) 94 | .expect("crypt32!CryptStringToBinaryA error getting flags param"); 95 | 96 | let dflags = match flags { 97 | 0x00000000 => "CRYPT_STRING_BASE64HEADER", 98 | 0x00000001 => "CRYPT_STRING_BASE64", 99 | 0x00000002 => "CRYPT_STRING_BINARY", 100 | 0x00000003 => "CRYPT_STRING_BASE64REQUESTHEADER", 101 | 0x00000004 => "CRYPT_STRING_HEX", 102 | 0x00000005 => "CRYPT_STRING_HEXASCII", 103 | 0x00000006 => "CRYPT_STRING_BASE64_ANY", 104 | 0x00000007 => "CRYPT_STRING_ANY", 105 | 0x00000008 => "CRYPT_STRING_HEX_ANY", 106 | 0x00000009 => "CRYPT_STRING_BASE64X509CRLHEADER", 107 | 0x0000000a => "CRYPT_STRING_HEXADDR", 108 | 0x0000000b => "CRYPT_STRING_HEXASCIIADDR", 109 | 0x0000000c => "CRYPT_STRING_HEXRAW", 110 | 0x20000000 => "CRYPT_STRING_STRICT", 111 | _ => "incorrect flag", 112 | }; 113 | 114 | log::info!( 115 | "{}** {} crypt32!CryptStringToBinaryA str: 0x{:x} len: {} ptr: {} len: {} {}{}", 116 | emu.colors.light_red, 117 | emu.pos, 118 | string, 119 | num_chars, 120 | ptr, 121 | inout_sz, 122 | dflags, 123 | emu.colors.nc 124 | ); 125 | 126 | for _ in 0..7 { 127 | emu.stack_pop32(false); 128 | } 129 | emu.regs.rax = 1; 130 | } 131 | -------------------------------------------------------------------------------- /libmwemu/src/winapi32/dnsapi.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi32::kernel32; 4 | //use crate::winapi32::helper; 5 | //use crate::endpoint; 6 | 7 | pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String { 8 | let api = kernel32::guess_api_name(emu, addr); 9 | match api.as_str() { 10 | "DnsQuery_A" => DnsQuery_A(emu), 11 | "DnsQueryA" => DnsQuery_A(emu), 12 | "DnsQuery_W" => DnsQuery_W(emu), 13 | "DnsQueryW" => DnsQuery_W(emu), 14 | 15 | _ => { 16 | if emu.cfg.skip_unimplemented == false { 17 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 18 | serialization::Serialization::dump_to_file( 19 | &emu, 20 | emu.cfg.dump_filename.as_ref().unwrap(), 21 | ); 22 | } 23 | 24 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 25 | } 26 | log::warn!( 27 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 28 | addr, 29 | api, 30 | emu.regs.rip 31 | ); 32 | return api; 33 | } 34 | } 35 | 36 | String::new() 37 | } 38 | 39 | fn DnsQuery_A(emu: &mut emu::Emu) { 40 | let name_ptr = emu 41 | .maps 42 | .read_dword(emu.regs.get_esp()) 43 | .expect("dnsapi!DnsQuery_A cant read name ptr param") as u64; 44 | let wtype = emu 45 | .maps 46 | .read_dword(emu.regs.get_esp() + 4) 47 | .expect("dnsapi!DnsQuery_A cant read wtype pram"); 48 | let opt = emu 49 | .maps 50 | .read_dword(emu.regs.get_esp() + 8) 51 | .expect("dnsapi!DnsQuery_A cant read options param"); 52 | let extra = emu 53 | .maps 54 | .read_dword(emu.regs.get_esp() + 12) 55 | .expect("dnsapi!DnsQuery_A cant read extra param"); 56 | let out_results = emu 57 | .maps 58 | .read_dword(emu.regs.get_esp() + 16) 59 | .expect("dnsapi!DnsQuery_A cant read out results param"); 60 | let out_reserved = emu 61 | .maps 62 | .read_dword(emu.regs.get_esp() + 20) 63 | .expect("dnsapi!DnsQuery_A cant read out reserved param"); 64 | 65 | let name = emu.maps.read_string(name_ptr); 66 | 67 | log::info!( 68 | "{}** {} dnsapi!DnsQuery_A '{}' {}", 69 | emu.colors.light_red, 70 | emu.pos, 71 | name, 72 | emu.colors.nc 73 | ); 74 | 75 | emu.regs.rax = 1; 76 | } 77 | 78 | fn DnsQuery_W(emu: &mut emu::Emu) { 79 | let name_ptr = emu 80 | .maps 81 | .read_dword(emu.regs.get_esp()) 82 | .expect("dnsapi!DnsQuery_W cant read name ptr param") as u64; 83 | let wtype = emu 84 | .maps 85 | .read_dword(emu.regs.get_esp() + 4) 86 | .expect("dnsapi!DnsQuery_W cant read wtype pram"); 87 | let opt = emu 88 | .maps 89 | .read_dword(emu.regs.get_esp() + 8) 90 | .expect("dnsapi!DnsQuery_W cant read options param"); 91 | let extra = emu 92 | .maps 93 | .read_dword(emu.regs.get_esp() + 12) 94 | .expect("dnsapi!DnsQuery_W cant read extra param"); 95 | let out_results = emu 96 | .maps 97 | .read_dword(emu.regs.get_esp() + 16) 98 | .expect("dnsapi!DnsQuery_W cant read out results param"); 99 | let out_reserved = emu 100 | .maps 101 | .read_dword(emu.regs.get_esp() + 20) 102 | .expect("dnsapi!DnsQuery_W cant read out reserved param"); 103 | 104 | let name = emu.maps.read_wide_string(name_ptr); 105 | 106 | log::info!( 107 | "{}** {} dnsapi!DnsQuery_W '{}' {}", 108 | emu.colors.light_red, 109 | emu.pos, 110 | name, 111 | emu.colors.nc 112 | ); 113 | 114 | emu.regs.rax = 1; 115 | } 116 | -------------------------------------------------------------------------------- /libmwemu/src/winapi32/helper.rs: -------------------------------------------------------------------------------- 1 | use lazy_static::lazy_static; 2 | use std::sync::Mutex; 3 | 4 | pub struct Handler { 5 | id: u64, 6 | uri: String, 7 | data: Vec, 8 | } 9 | 10 | impl Handler { 11 | fn new(id: u64, uri: &str) -> Handler { 12 | Handler { 13 | id, 14 | uri: uri.to_string(), 15 | data: vec![], 16 | } 17 | } 18 | } 19 | 20 | lazy_static! { 21 | static ref HANDLERS: Mutex> = Mutex::new(Vec::new()); 22 | static ref SOCKETS: Mutex> = Mutex::new(vec![0; 0]); 23 | } 24 | 25 | pub fn handler_create(uri: &str) -> u64 { 26 | let mut handles = HANDLERS.lock().unwrap(); 27 | 28 | let new_id: u64 = if handles.len() == 0 { 29 | 1 30 | } else { 31 | let last_id = handles[handles.len() - 1].id; 32 | last_id + 1 33 | }; 34 | 35 | let new_handler = Handler::new(new_id, uri); 36 | 37 | handles.push(new_handler); 38 | new_id 39 | } 40 | 41 | pub fn handler_close(hndl: u64) -> bool { 42 | let mut handles = HANDLERS.lock().unwrap(); 43 | let idx = match handles.iter().position(|h| h.id == hndl) { 44 | Some(i) => i, 45 | None => return false, 46 | }; 47 | handles.remove(idx); 48 | true 49 | } 50 | 51 | pub fn handler_print() { 52 | let hndls = HANDLERS.lock().unwrap(); 53 | for h in hndls.iter() { 54 | log::info!("{:x} {}", h.id, h.uri); 55 | } 56 | } 57 | 58 | pub fn handler_exist(hndl: u64) -> bool { 59 | let handles = HANDLERS.lock().unwrap(); 60 | match handles.iter().position(|h| h.id == hndl) { 61 | Some(_) => true, 62 | None => false, 63 | } 64 | } 65 | 66 | pub fn handler_put_bytes(hndl: u64, data: &[u8]) { 67 | let mut handles = HANDLERS.lock().unwrap(); 68 | match handles.iter().position(|h| h.id == hndl) { 69 | Some(idx) => handles[idx].data = data.to_vec(), 70 | None => (), 71 | } 72 | } 73 | 74 | pub fn handler_get_uri(hndl: u64) -> String { 75 | let handles = HANDLERS.lock().unwrap(); 76 | match handles.iter().position(|h| h.id == hndl) { 77 | Some(idx) => handles[idx].uri.clone(), 78 | None => String::new(), 79 | } 80 | } 81 | 82 | pub fn socket_create() -> u64 { 83 | let mut sockets = SOCKETS.lock().unwrap(); 84 | 85 | let new_socket: u64 = if sockets.len() == 0 { 86 | sockets.push(0); // stdin 87 | sockets.push(1); // stdout 88 | sockets.push(2); // stderr 89 | 3 // first available socket 90 | } else { 91 | let last_socket = sockets[sockets.len() - 1]; 92 | last_socket + 1 93 | }; 94 | 95 | sockets.push(new_socket); 96 | new_socket 97 | } 98 | 99 | pub fn socket_close(sock: u64) -> bool { 100 | let mut sockets = SOCKETS.lock().unwrap(); 101 | let idx = match sockets.iter().position(|s| *s == sock) { 102 | Some(i) => i, 103 | None => return false, 104 | }; 105 | sockets.remove(idx); 106 | true 107 | } 108 | 109 | pub fn socket_exist(sock: u64) -> bool { 110 | let sockets = SOCKETS.lock().unwrap(); 111 | match sockets.iter().position(|s| *s == sock) { 112 | Some(_) => true, 113 | None => false, 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /libmwemu/src/winapi32/iphlpapi.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi32::kernel32; 4 | 5 | pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String { 6 | let api = kernel32::guess_api_name(emu, addr); 7 | match api.as_str() { 8 | _ => { 9 | if emu.cfg.skip_unimplemented == false { 10 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 11 | serialization::Serialization::dump_to_file( 12 | &emu, 13 | emu.cfg.dump_filename.as_ref().unwrap(), 14 | ); 15 | } 16 | 17 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 18 | } 19 | log::warn!( 20 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 21 | addr, 22 | api, 23 | emu.regs.rip 24 | ); 25 | return api; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /libmwemu/src/winapi32/kernelbase.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | //use crate::console; 3 | //use crate::constants; 4 | //use crate::context32; 5 | //use crate::peb32; 6 | //use crate::structures; 7 | //use crate::winapi32::helper; 8 | use crate::serialization; 9 | use crate::winapi32::kernel32; 10 | 11 | use lazy_static::lazy_static; 12 | use std::sync::Mutex; 13 | 14 | pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String { 15 | let api = kernel32::guess_api_name(emu, addr); 16 | match api.as_str() { 17 | "LoadStringW" => LoadStringW(emu), 18 | "_initterm" => _initterm(emu), 19 | "_initterm_e" => _initterm_e(emu), 20 | 21 | _ => { 22 | if emu.cfg.skip_unimplemented == false { 23 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 24 | serialization::Serialization::dump_to_file( 25 | &emu, 26 | emu.cfg.dump_filename.as_ref().unwrap(), 27 | ); 28 | } 29 | 30 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 31 | } 32 | log::warn!( 33 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 34 | addr, 35 | api, 36 | emu.regs.rip 37 | ); 38 | return api; 39 | } 40 | } 41 | 42 | String::new() 43 | } 44 | 45 | lazy_static! { 46 | static ref COUNT_READ: Mutex = Mutex::new(0); 47 | static ref COUNT_WRITE: Mutex = Mutex::new(0); 48 | static ref LAST_ERROR: Mutex = Mutex::new(0); 49 | } 50 | 51 | /// kernelbase API //// 52 | 53 | fn LoadStringW(emu: &mut emu::Emu) { 54 | let hndl = emu 55 | .maps 56 | .read_dword(emu.regs.rsp) 57 | .expect("kernelbase!LoadStringW error reading param"); 58 | let id = emu 59 | .maps 60 | .read_dword(emu.regs.rsp + 4) 61 | .expect("kernelbase!LoadStringW error reading param"); 62 | let buff = emu 63 | .maps 64 | .read_dword(emu.regs.rsp + 8) 65 | .expect("kernelbase!LoadStringW error reading param"); 66 | let len = emu 67 | .maps 68 | .read_dword(emu.regs.rsp + 12) 69 | .expect("kernelbase!LoadStringW error reading param"); 70 | 71 | log::info!( 72 | "{}** {} kernelbase!LoadStringW {} 0x{} {}", 73 | emu.colors.light_red, 74 | emu.pos, 75 | id, 76 | buff, 77 | emu.colors.nc, 78 | ); 79 | 80 | emu.stack_pop32(false); 81 | emu.stack_pop32(false); 82 | emu.stack_pop32(false); 83 | emu.stack_pop32(false); 84 | emu.regs.rax = 1; 85 | } 86 | 87 | fn _initterm(emu: &mut emu::Emu) { 88 | let ptr1 = emu 89 | .maps 90 | .read_dword(emu.regs.rsp) 91 | .expect("kernelbase!_initterm error reading param"); 92 | let ptr2 = emu 93 | .maps 94 | .read_dword(emu.regs.rsp + 4) 95 | .expect("kernelbase!_initterm error reading param"); 96 | log::info!( 97 | "{}** {} kernelbase!_initterm 0x{:x} 0x{:x} {}", 98 | emu.colors.light_red, 99 | emu.pos, 100 | ptr1, 101 | ptr2, 102 | emu.colors.nc 103 | ); 104 | emu.stack_pop32(false); 105 | emu.stack_pop32(false); 106 | emu.regs.rax = 0; 107 | } 108 | 109 | fn _initterm_e(emu: &mut emu::Emu) { 110 | let ptr1 = emu 111 | .maps 112 | .read_dword(emu.regs.rsp) 113 | .expect("kernelbase!_initterm_e error reading param"); 114 | let ptr2 = emu 115 | .maps 116 | .read_dword(emu.regs.rsp + 4) 117 | .expect("kernelbase!_initterm_e error reading param"); 118 | log::info!( 119 | "{}** {} kernelbase!_initterm_e 0x{:x} 0x{:x} {}", 120 | emu.colors.light_red, 121 | emu.pos, 122 | ptr1, 123 | ptr2, 124 | emu.colors.nc 125 | ); 126 | emu.stack_pop32(false); 127 | emu.stack_pop32(false); 128 | emu.regs.rax = 0; 129 | } 130 | -------------------------------------------------------------------------------- /libmwemu/src/winapi32/libgcc.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | //use crate::constants::*; 3 | //use crate::winapi32::helper; 4 | use crate::serialization; 5 | use crate::winapi32::kernel32; 6 | 7 | pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String { 8 | let api = kernel32::guess_api_name(emu, addr); 9 | match api.as_str() { 10 | "__register_frame_info" => __register_frame_info(emu), 11 | "__deregister_frame_info" => __deregister_frame_info(emu), 12 | 13 | _ => { 14 | if emu.cfg.skip_unimplemented == false { 15 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 16 | serialization::Serialization::dump_to_file( 17 | &emu, 18 | emu.cfg.dump_filename.as_ref().unwrap(), 19 | ); 20 | } 21 | 22 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 23 | } 24 | log::warn!( 25 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 26 | addr, 27 | api, 28 | emu.regs.rip 29 | ); 30 | return api; 31 | } 32 | } 33 | 34 | String::new() 35 | } 36 | 37 | fn __register_frame_info(emu: &mut emu::Emu) { 38 | let p1 = emu 39 | .maps 40 | .read_dword(emu.regs.get_esp()) 41 | .expect("advapi32!__register_frame_info error reading param"); 42 | let p2 = emu 43 | .maps 44 | .read_dword(emu.regs.get_esp() + 4) 45 | .expect("advapi32!__register_frame_info error reading param"); 46 | 47 | log::info!( 48 | "{}** {} libgcc!__register_frame_info {:x} {:x} {}", 49 | emu.colors.light_red, 50 | emu.pos, 51 | p1, 52 | p2, 53 | emu.colors.nc 54 | ); 55 | 56 | let mem = match emu.maps.get_mem_by_addr_mut(0x40E198) { 57 | Some(m) => m, 58 | None => emu 59 | .maps 60 | .create_map("glob1", 0x40E198, 100) 61 | .expect("cannot create glob1 map"), 62 | }; 63 | 64 | mem.write_dword(0x40E198, 0x6e940000); 65 | 66 | for _ in 0..2 { 67 | emu.stack_pop32(false); 68 | } 69 | emu.regs.rax = 1; 70 | } 71 | 72 | fn __deregister_frame_info(emu: &mut emu::Emu) { 73 | let p1 = emu 74 | .maps 75 | .read_dword(emu.regs.get_esp()) 76 | .expect("advapi32!__deregister_frame_info error reading param"); 77 | 78 | log::info!( 79 | "{}** {} libgcc!__deregister_frame_info {:x} {}", 80 | emu.colors.light_red, 81 | emu.pos, 82 | p1, 83 | emu.colors.nc 84 | ); 85 | 86 | emu.stack_pop32(false); 87 | emu.regs.rax = 1; 88 | } 89 | -------------------------------------------------------------------------------- /libmwemu/src/winapi32/mod.rs: -------------------------------------------------------------------------------- 1 | mod advapi32; 2 | mod crypt32; 3 | mod dnsapi; 4 | pub mod helper; 5 | mod iphlpapi; 6 | pub mod kernel32; 7 | mod kernelbase; 8 | mod libgcc; 9 | mod mscoree; 10 | mod msvcrt; 11 | mod ntdll; 12 | mod oleaut32; 13 | mod shlwapi; 14 | mod user32; 15 | mod wincrt; 16 | mod wininet; 17 | mod ws2_32; 18 | 19 | use crate::emu; 20 | 21 | pub fn gateway(addr: u32, name: String, emu: &mut emu::Emu) { 22 | emu.regs.sanitize32(); 23 | match name.as_str() { 24 | "kernel32.text" => kernel32::gateway(addr, emu), 25 | "kernel32.rdata" => kernel32::gateway(addr, emu), 26 | "ntdll.text" => ntdll::gateway(addr, emu), 27 | "user32.text" => user32::gateway(addr, emu), 28 | "ws2_32.text" => ws2_32::gateway(addr, emu), 29 | "wininet.text" => wininet::gateway(addr, emu), 30 | "advapi32.text" => advapi32::gateway(addr, emu), 31 | "crypt32.text" => crypt32::gateway(addr, emu), 32 | "dnsapi.text" => dnsapi::gateway(addr, emu), 33 | "mscoree.text" => mscoree::gateway(addr, emu), 34 | "msvcrt.text" => msvcrt::gateway(addr, emu), 35 | "shlwapi.text" => shlwapi::gateway(addr, emu), 36 | "oleaut32.text" => oleaut32::gateway(addr, emu), 37 | "kernelbase.text" => kernelbase::gateway(addr, emu), 38 | "iphlpapi.text" => iphlpapi::gateway(addr, emu), 39 | "libgcc_s_dw2-1.text" => libgcc::gateway(addr, emu), 40 | "api-ms-win-crt-runtime-l1-1-0.text" => wincrt::gateway(addr, emu), 41 | "not_loaded" => { 42 | // TODO: banzai check? 43 | emu.pe32.as_ref().unwrap().import_addr_to_name(addr) 44 | } 45 | _ => panic!("/!\\ trying to execute on {} at 0x{:x}", name, addr), 46 | }; 47 | emu.call_stack.pop(); 48 | } 49 | -------------------------------------------------------------------------------- /libmwemu/src/winapi32/mscoree.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi32::kernel32; 4 | 5 | pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String { 6 | let api = kernel32::guess_api_name(emu, addr); 7 | match api.as_str() { 8 | "_CorExeMain" => _CorExeMain(emu), 9 | 10 | _ => { 11 | if emu.cfg.skip_unimplemented == false { 12 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 13 | serialization::Serialization::dump_to_file( 14 | &emu, 15 | emu.cfg.dump_filename.as_ref().unwrap(), 16 | ); 17 | } 18 | 19 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 20 | } 21 | log::warn!( 22 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 23 | addr, 24 | api, 25 | emu.regs.rip 26 | ); 27 | return api; 28 | } 29 | } 30 | 31 | String::new() 32 | } 33 | 34 | pub fn _CorExeMain(emu: &mut emu::Emu) { 35 | log::info!( 36 | "{}** {} mscoree!_CorExeMain {}", 37 | emu.colors.light_red, 38 | emu.pos, 39 | emu.colors.nc 40 | ); 41 | emu.regs.rax = 1; 42 | unimplemented!(); 43 | } 44 | -------------------------------------------------------------------------------- /libmwemu/src/winapi32/oleaut32.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi32::kernel32; 4 | //use crate::winapi32::helper; 5 | 6 | pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String { 7 | let api = kernel32::guess_api_name(emu, addr); 8 | match api.as_str() { 9 | "SysAllocStringLen" => SysAllocStringLen(emu), 10 | "SysFreeString" => SysFreeString(emu), 11 | 12 | _ => { 13 | if emu.cfg.skip_unimplemented == false { 14 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 15 | serialization::Serialization::dump_to_file( 16 | &emu, 17 | emu.cfg.dump_filename.as_ref().unwrap(), 18 | ); 19 | } 20 | 21 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 22 | } 23 | log::warn!( 24 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 25 | addr, 26 | api, 27 | emu.regs.rip 28 | ); 29 | return api; 30 | } 31 | } 32 | 33 | String::new() 34 | } 35 | 36 | fn SysAllocStringLen(emu: &mut emu::Emu) { 37 | let str_ptr = emu 38 | .maps 39 | .read_dword(emu.regs.get_esp()) 40 | .expect("oleaut32!SysAllocStringLen cannot read str_ptr") as u64; 41 | let mut size = emu 42 | .maps 43 | .read_dword(emu.regs.get_esp() + 4) 44 | .expect("oleaut32!SysAllocStringLen cannot read size") as u64; 45 | 46 | if size == 0xffffffff { 47 | size = 1024; 48 | } 49 | size += 1; // null byte 50 | size += 8; // metadata 51 | 52 | let base = emu 53 | .maps 54 | .alloc(size + 8) 55 | .expect("oleaut32!SysAllocStringLen out of memory"); 56 | let name = format!("alloc_{:x}", base + 8); 57 | emu.maps.create_map(&name, base, size); 58 | emu.maps.memcpy(base + 8, str_ptr, size as usize - 1); 59 | 60 | log::info!( 61 | "{}** {} oleaut32!SysAllocStringLen ={} {} {}", 62 | emu.colors.light_red, 63 | emu.pos, 64 | name, 65 | size - 8, 66 | emu.colors.nc 67 | ); 68 | 69 | for _ in 0..2 { 70 | emu.stack_pop32(false); 71 | } 72 | 73 | emu.regs.rax = base + 8; 74 | } 75 | 76 | fn SysFreeString(emu: &mut emu::Emu) { 77 | let str_ptr = emu 78 | .maps 79 | .read_dword(emu.regs.get_esp()) 80 | .expect("oleaut32!SysFreeString cannot read host_port") as u64; 81 | 82 | log::info!( 83 | "{}** {} oleaut32!SysFreeString 0x{:x} {}", 84 | emu.colors.light_red, 85 | emu.pos, 86 | str_ptr, 87 | emu.colors.nc 88 | ); 89 | 90 | //emu.maps.free(&format!("alloc_{:x}", str_ptr)); 91 | 92 | emu.stack_pop32(false); 93 | } 94 | -------------------------------------------------------------------------------- /libmwemu/src/winapi32/shlwapi.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi32::kernel32; 4 | //use crate::winapi32::helper; 5 | //use crate::endpoint; 6 | 7 | pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String { 8 | let api = kernel32::guess_api_name(emu, addr); 9 | match api.as_str() { 10 | _ => { 11 | if emu.cfg.skip_unimplemented == false { 12 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 13 | serialization::Serialization::dump_to_file( 14 | &emu, 15 | emu.cfg.dump_filename.as_ref().unwrap(), 16 | ); 17 | } 18 | 19 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 20 | } 21 | log::warn!( 22 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 23 | addr, 24 | api, 25 | emu.regs.rip 26 | ); 27 | return api; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /libmwemu/src/winapi32/wincrt.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | //use crate::constants::*; 3 | //use crate::winapi32::helper; 4 | use crate::serialization; 5 | use crate::winapi32::kernel32; 6 | 7 | pub fn gateway(addr: u32, emu: &mut emu::Emu) -> String { 8 | let api = kernel32::guess_api_name(emu, addr); 9 | match api.as_str() { 10 | "_set_invalid_parameter_handler" => set_invalid_parameter_handler(emu), 11 | 12 | _ => { 13 | if emu.cfg.skip_unimplemented == false { 14 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 15 | serialization::Serialization::dump_to_file( 16 | &emu, 17 | emu.cfg.dump_filename.as_ref().unwrap(), 18 | ); 19 | } 20 | 21 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 22 | } 23 | log::warn!( 24 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 25 | addr, 26 | api, 27 | emu.regs.rip 28 | ); 29 | return api; 30 | } 31 | } 32 | 33 | String::new() 34 | } 35 | 36 | fn set_invalid_parameter_handler(emu: &mut emu::Emu) { 37 | log::info!( 38 | "{}** {} wincrt!_set_invalid_parameter_handler {}", 39 | emu.colors.light_red, 40 | emu.pos, 41 | emu.colors.nc 42 | ); 43 | emu.regs.rax = 0; 44 | } 45 | -------------------------------------------------------------------------------- /libmwemu/src/winapi64/advapi32.rs: -------------------------------------------------------------------------------- 1 | use crate::constants; 2 | use crate::emu; 3 | use crate::serialization; 4 | use crate::winapi32::helper; 5 | use crate::winapi64; 6 | 7 | pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String { 8 | let api = winapi64::kernel32::guess_api_name(emu, addr); 9 | match api.as_str() { 10 | "StartServiceCtrlDispatcherA" => StartServiceCtrlDispatcherA(emu), 11 | "StartServiceCtrlDispatcherW" => StartServiceCtrlDispatcherW(emu), 12 | "RegOpenKeyExA" => RegOpenKeyExA(emu), 13 | "RegQueryValueExA" => RegQueryValueExA(emu), 14 | "RegCloseKey" => RegCloseKey(emu), 15 | 16 | _ => { 17 | if emu.cfg.skip_unimplemented == false { 18 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 19 | serialization::Serialization::dump_to_file( 20 | &emu, 21 | emu.cfg.dump_filename.as_ref().unwrap(), 22 | ); 23 | } 24 | 25 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 26 | } 27 | log::warn!( 28 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 29 | addr, 30 | api, 31 | emu.regs.rip 32 | ); 33 | return api; 34 | } 35 | } 36 | 37 | String::new() 38 | } 39 | 40 | fn StartServiceCtrlDispatcherA(emu: &mut emu::Emu) { 41 | let service_table_entry_ptr = emu 42 | .maps 43 | .read_dword(emu.regs.get_esp()) 44 | .expect("advapi32!StartServiceCtrlDispatcherA error reading service_table_entry pointer"); 45 | 46 | let service_name = emu 47 | .maps 48 | .read_dword(service_table_entry_ptr as u64) 49 | .expect("advapi32!StartServiceCtrlDispatcherA error reading service_name"); 50 | let service_name = emu 51 | .maps 52 | .read_dword((service_table_entry_ptr + 4) as u64) 53 | .expect("advapi32!StartServiceCtrlDispatcherA error reading service_name"); 54 | 55 | emu.regs.set_eax(1); 56 | } 57 | 58 | fn StartServiceCtrlDispatcherW(emu: &mut emu::Emu) { 59 | let service_table_entry_ptr = emu 60 | .maps 61 | .read_dword(emu.regs.get_esp()) 62 | .expect("advapi32!StartServiceCtrlDispatcherW error reading service_table_entry pointer"); 63 | 64 | emu.regs.set_eax(1); 65 | } 66 | 67 | fn RegOpenKeyExA(emu: &mut emu::Emu) { 68 | let hkey = emu.regs.rcx; 69 | let subkey_ptr = emu.regs.rdx; 70 | let opts = emu.regs.r8; 71 | let result = emu.regs.r9; 72 | 73 | let subkey = emu.maps.read_string(subkey_ptr); 74 | 75 | log::info!( 76 | "{}** {} advapi32!RegOpenKeyExA {} {}", 77 | emu.colors.light_red, 78 | emu.pos, 79 | subkey, 80 | emu.colors.nc 81 | ); 82 | 83 | emu.maps 84 | .write_qword(result, helper::handler_create(&subkey)); 85 | emu.regs.rax = constants::ERROR_SUCCESS; 86 | } 87 | 88 | fn RegCloseKey(emu: &mut emu::Emu) { 89 | let hkey = emu.regs.rcx; 90 | 91 | log::info!( 92 | "{}** {} advapi32!RegCloseKey {}", 93 | emu.colors.light_red, 94 | emu.pos, 95 | emu.colors.nc 96 | ); 97 | 98 | helper::handler_close(hkey); 99 | 100 | emu.regs.rax = constants::ERROR_SUCCESS; 101 | } 102 | 103 | fn RegQueryValueExA(emu: &mut emu::Emu) { 104 | let hkey = emu.regs.rcx; 105 | let value_ptr = emu.regs.rdx; 106 | let reserved = emu.regs.r8; 107 | let typ_out = emu.regs.r9; 108 | let data_out = emu 109 | .maps 110 | .read_qword(emu.regs.rsp + 0x20) 111 | .expect("error reading api aparam"); 112 | let datasz_out = emu 113 | .maps 114 | .read_qword(emu.regs.rsp + 0x28) 115 | .expect("error reading api param"); 116 | 117 | let mut value = String::new(); 118 | if value_ptr > 0 { 119 | value = emu.maps.read_string(value_ptr); 120 | } 121 | 122 | log::info!( 123 | "{}** {} advapi32!RegQueryValueExA {} {}", 124 | emu.colors.light_red, 125 | emu.pos, 126 | value, 127 | emu.colors.nc 128 | ); 129 | 130 | if data_out > 0 { 131 | emu.maps.write_string(data_out, "some_random_reg_contents"); 132 | } 133 | if datasz_out > 0 { 134 | emu.maps.write_qword(datasz_out, 24); 135 | } 136 | emu.regs.rax = constants::ERROR_SUCCESS; 137 | } 138 | -------------------------------------------------------------------------------- /libmwemu/src/winapi64/comctl32.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi64; 4 | 5 | pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String { 6 | let api = winapi64::kernel32::guess_api_name(emu, addr); 7 | match api.as_str() { 8 | "InitCommonControls" => InitCommonControls(emu), 9 | "InitCommonControlsEx" => InitCommonControlsEx(emu), 10 | _ => { 11 | if emu.cfg.skip_unimplemented == false { 12 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 13 | serialization::Serialization::dump_to_file( 14 | &emu, 15 | emu.cfg.dump_filename.as_ref().unwrap(), 16 | ); 17 | } 18 | 19 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 20 | } 21 | log::warn!( 22 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 23 | addr, 24 | api, 25 | emu.regs.rip 26 | ); 27 | return api; 28 | } 29 | } 30 | String::new() 31 | } 32 | 33 | /* 34 | void InitCommonControls(); 35 | */ 36 | fn InitCommonControls(emu: &mut emu::Emu) { 37 | log::info!( 38 | "{}** {} comctl32!InitCommonControls {}", 39 | emu.colors.light_red, 40 | emu.pos, 41 | emu.colors.nc 42 | ); 43 | // TODO: do something 44 | } 45 | 46 | /* 47 | BOOL InitCommonControlsEx( 48 | [in] const INITCOMMONCONTROLSEX *piccs 49 | ); 50 | */ 51 | fn InitCommonControlsEx(emu: &mut emu::Emu) { 52 | log::info!( 53 | "{}** {} comctl32!InitCommonControlsEx {}", 54 | emu.colors.light_red, 55 | emu.pos, 56 | emu.colors.nc 57 | ); 58 | // TODO: do something 59 | emu.regs.rax = 1; // TRUE 60 | } 61 | -------------------------------------------------------------------------------- /libmwemu/src/winapi64/comctl64.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi64::kernel32; 4 | //use crate::winapi32::helper; 5 | 6 | pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String { 7 | let api = kernel32::guess_api_name(emu, addr); 8 | match api.as_str() { 9 | _ => { 10 | if emu.cfg.skip_unimplemented == false { 11 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 12 | serialization::Serialization::dump_to_file( 13 | &emu, 14 | emu.cfg.dump_filename.as_ref().unwrap(), 15 | ); 16 | } 17 | 18 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 19 | } 20 | log::warn!( 21 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 22 | addr, 23 | api, 24 | emu.regs.rip 25 | ); 26 | return api; 27 | } 28 | } 29 | 30 | //String::new() 31 | } 32 | -------------------------------------------------------------------------------- /libmwemu/src/winapi64/dnsapi.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi64; 4 | 5 | pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String { 6 | let api = winapi64::kernel32::guess_api_name(emu, addr); 7 | match api.as_str() { 8 | _ => { 9 | if emu.cfg.skip_unimplemented == false { 10 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 11 | serialization::Serialization::dump_to_file( 12 | &emu, 13 | emu.cfg.dump_filename.as_ref().unwrap(), 14 | ); 15 | } 16 | 17 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 18 | } 19 | log::warn!( 20 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 21 | addr, 22 | api, 23 | emu.regs.rip 24 | ); 25 | return api; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /libmwemu/src/winapi64/gdi32.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi64; 4 | 5 | pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String { 6 | let api = winapi64::kernel32::guess_api_name(emu, addr); 7 | match api.as_str() { 8 | "CreateFontIndirectA" => CreateFontIndirectA(emu), 9 | "GetDeviceCaps" => GetDeviceCaps(emu), 10 | _ => { 11 | if emu.cfg.skip_unimplemented == false { 12 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 13 | serialization::Serialization::dump_to_file( 14 | &emu, 15 | emu.cfg.dump_filename.as_ref().unwrap(), 16 | ); 17 | } 18 | 19 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 20 | } 21 | log::warn!( 22 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 23 | addr, 24 | api, 25 | emu.regs.rip 26 | ); 27 | return api; 28 | } 29 | } 30 | String::new() 31 | } 32 | 33 | /* 34 | HFONT CreateFontIndirectA( 35 | [in] const LOGFONTA *lplf 36 | ); 37 | */ 38 | fn CreateFontIndirectA(emu: &mut emu::Emu) { 39 | log_red!(emu, "** {} gdi32!CreateFontIndirectA", emu.pos); 40 | // TODO: return a handle to a logical font? 41 | // TODO: don't return failure 42 | emu.regs.rax = 0; 43 | } 44 | 45 | /* 46 | int GetDeviceCaps( 47 | [in] HDC hdc, 48 | [in] int index 49 | ); 50 | */ 51 | fn GetDeviceCaps(emu: &mut emu::Emu) { 52 | let hdc = emu.regs.rcx; 53 | let index = emu.regs.rdx; 54 | log_red!(emu, "** {} gdi32!GetDeviceCaps {} {}", emu.pos, hdc, index); 55 | // TODO: do something 56 | emu.regs.rax = 0; 57 | } 58 | -------------------------------------------------------------------------------- /libmwemu/src/winapi64/mod.rs: -------------------------------------------------------------------------------- 1 | mod advapi32; 2 | mod comctl32; 3 | mod comctl64; 4 | mod dnsapi; 5 | mod gdi32; 6 | pub mod kernel32; 7 | mod kernelbase; 8 | mod msvcrt; 9 | mod ntdll; 10 | mod ole32; 11 | mod oleaut32; 12 | mod shell32; 13 | mod shlwapi; 14 | mod user32; 15 | mod uxtheme; 16 | mod wincrt; 17 | mod winhttp; 18 | mod wininet; 19 | mod ws2_32; 20 | 21 | use crate::emu; 22 | 23 | pub fn gateway(addr: u64, name: String, emu: &mut emu::Emu) { 24 | match name.as_str() { 25 | "kernel32.text" => kernel32::gateway(addr, emu), 26 | "kernel32.rdata" => kernel32::gateway(addr, emu), 27 | "ntdll.text" => ntdll::gateway(addr, emu), 28 | "user32.text" => user32::gateway(addr, emu), 29 | "ws2_32.text" => ws2_32::gateway(addr, emu), 30 | "wininet.text" => wininet::gateway(addr, emu), 31 | "advapi32.text" => advapi32::gateway(addr, emu), 32 | "winhttp.text" => winhttp::gateway(addr, emu), 33 | "dnsapi.text" => dnsapi::gateway(addr, emu), 34 | "comctl32.text" => comctl32::gateway(addr, emu), 35 | "comctl64.text" => comctl64::gateway(addr, emu), 36 | "shell32.text" => shell32::gateway(addr, emu), 37 | "shlwapi.text" => shlwapi::gateway(addr, emu), 38 | "kernelbase.text" => kernelbase::gateway(addr, emu), 39 | "oleaut32.text" => oleaut32::gateway(addr, emu), 40 | "uxtheme.text" => uxtheme::gateway(addr, emu), 41 | "gdi32.text" => gdi32::gateway(addr, emu), 42 | "ole32.text" => ole32::gateway(addr, emu), 43 | "msvcrt.text" => msvcrt::gateway(addr, emu), 44 | "api-ms-win-crt-runtime-l1-1-0.rdata" => wincrt::gateway(addr, emu), 45 | "api-ms-win-crt-stdio-l1-1-0.rdata" => wincrt::gateway(addr, emu), 46 | "api-ms-win-crt-heap-l1-1-0.rdata" => wincrt::gateway(addr, emu), 47 | "not_loaded" => { 48 | // TODO: banzai check? 49 | emu.pe64.as_ref().unwrap().import_addr_to_name(addr) 50 | } 51 | _ => panic!("/!\\ trying to execute on {} at 0x{:x}", name, addr), 52 | }; 53 | 54 | emu.call_stack.pop(); 55 | } 56 | -------------------------------------------------------------------------------- /libmwemu/src/winapi64/msvcrt.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi64::kernel32; 4 | 5 | pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String { 6 | let api = kernel32::guess_api_name(emu, addr); 7 | 8 | match api.as_str() { 9 | "__set_app_type" => __set_app_type(emu), 10 | "malloc" => malloc(emu), 11 | _ => { 12 | if emu.cfg.skip_unimplemented == false { 13 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 14 | serialization::Serialization::dump_to_file( 15 | &emu, 16 | emu.cfg.dump_filename.as_ref().unwrap(), 17 | ); 18 | } 19 | 20 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 21 | } 22 | log::warn!( 23 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 24 | addr, 25 | api, 26 | emu.regs.rip 27 | ); 28 | return api; 29 | } 30 | } 31 | 32 | String::new() 33 | } 34 | 35 | /* 36 | void __set_app_type ( 37 | int at 38 | ) 39 | */ 40 | fn __set_app_type(emu: &mut emu::Emu) { 41 | let app_type = emu.regs.rcx; 42 | log_red!( 43 | emu, 44 | "** {} msvcrt!__set_app_type app_type: 0x{:x}", 45 | emu.pos, 46 | app_type 47 | ); 48 | } 49 | 50 | fn malloc(emu: &mut emu::Emu) { 51 | let size = emu.regs.rcx; 52 | 53 | if size > 0 { 54 | let base = emu.maps.alloc(size).expect("msvcrt!malloc out of memory"); 55 | 56 | emu.maps 57 | .create_map(&format!("alloc_{:x}", base), base, size) 58 | .expect("msvcrt!malloc cannot create map"); 59 | 60 | log::info!( 61 | "{}** {} msvcrt!malloc sz: {} addr: 0x{:x} {}", 62 | emu.colors.light_red, 63 | emu.pos, 64 | size, 65 | base, 66 | emu.colors.nc 67 | ); 68 | 69 | emu.regs.rax = base; 70 | } else { 71 | emu.regs.rax = 0x1337; // weird msvcrt has to return a random unallocated pointer, and the program has to do free() on it 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /libmwemu/src/winapi64/ole32.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi64::kernel32; 4 | //use crate::winapi32::helper; 5 | 6 | pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String { 7 | let api = kernel32::guess_api_name(emu, addr); 8 | match api.as_str() { 9 | "OleInitialize" => OleInitialize(emu), 10 | _ => { 11 | if emu.cfg.skip_unimplemented == false { 12 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 13 | serialization::Serialization::dump_to_file( 14 | &emu, 15 | emu.cfg.dump_filename.as_ref().unwrap(), 16 | ); 17 | } 18 | 19 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 20 | } 21 | log::warn!( 22 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 23 | addr, 24 | api, 25 | emu.regs.rip 26 | ); 27 | return api; 28 | } 29 | } 30 | 31 | String::new() 32 | } 33 | 34 | /* 35 | HRESULT OleInitialize( 36 | [in] LPVOID pvReserved 37 | ); 38 | */ 39 | fn OleInitialize(emu: &mut emu::Emu) { 40 | log::info!( 41 | "{}** {} ole32!OleInitialize {}", 42 | emu.colors.light_red, 43 | emu.pos, 44 | emu.colors.nc 45 | ); 46 | // TODO: do something 47 | emu.regs.rax = 0; // S_OK 48 | } 49 | -------------------------------------------------------------------------------- /libmwemu/src/winapi64/oleaut32.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi64::kernel32; 4 | //use crate::winapi32::helper; 5 | 6 | pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String { 7 | let api = kernel32::guess_api_name(emu, addr); 8 | match api.as_str() { 9 | "SysAllocStringLen" => SysAllocStringLen(emu), 10 | "SysReAllocStringLen" => SysReAllocStringLen(emu), 11 | "SysFreeString" => SysFreeString(emu), 12 | "VariantClear" => VariantClear(emu), 13 | 14 | _ => { 15 | if emu.cfg.skip_unimplemented == false { 16 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 17 | serialization::Serialization::dump_to_file( 18 | &emu, 19 | emu.cfg.dump_filename.as_ref().unwrap(), 20 | ); 21 | } 22 | 23 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 24 | } 25 | log::warn!( 26 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 27 | addr, 28 | api, 29 | emu.regs.rip 30 | ); 31 | return api; 32 | } 33 | } 34 | 35 | String::new() 36 | } 37 | 38 | fn SysAllocStringLen(emu: &mut emu::Emu) { 39 | let str_ptr = emu.regs.rcx; 40 | let mut size = emu.regs.rdx; 41 | 42 | log::info!( 43 | "{}** {}:{:x} oleaut32!SysAllocStringLen str_ptr: 0x{:x} size: {}", 44 | emu.colors.light_red, 45 | emu.pos, 46 | emu.regs.rip, 47 | str_ptr, 48 | size 49 | ); 50 | 51 | if size == 0xffffffff { 52 | size = 1024; 53 | } 54 | size += 1; // null byte 55 | size += 8; // metadata 56 | 57 | let base = emu 58 | .maps 59 | .alloc(size + 100) 60 | .expect("oleaut32!SysAllocStringLen out of memory"); 61 | let name = format!("alloc_{:x}", base); 62 | emu.maps.create_map(&name, base, size + 100); 63 | 64 | // watch out for null? 65 | if str_ptr != 0 { 66 | emu.maps.memcpy(base + 8, str_ptr, size as usize - 1); 67 | } 68 | 69 | log::info!( 70 | "{}** {}:{:x} oleaut32!SysAllocStringLen ={} {} {}", 71 | emu.colors.light_red, 72 | emu.pos, 73 | emu.regs.rip, 74 | name, 75 | size - 8, 76 | emu.colors.nc 77 | ); 78 | 79 | emu.regs.rax = base + 8; 80 | } 81 | 82 | fn SysFreeString(emu: &mut emu::Emu) { 83 | let str_ptr = emu.regs.rcx; 84 | 85 | log::info!( 86 | "{}** {} oleaut32!SysFreeString 0x{:x} {}", 87 | emu.colors.light_red, 88 | emu.pos, 89 | str_ptr, 90 | emu.colors.nc 91 | ); 92 | 93 | //emu.maps.free(&format!("alloc_{:x}", str_ptr)); 94 | } 95 | 96 | /* 97 | INT SysReAllocStringLen( 98 | [in, out] BSTR *pbstr, 99 | [in, optional] const OLECHAR *psz, 100 | [in] unsigned int len 101 | ); 102 | */ 103 | fn SysReAllocStringLen(emu: &mut emu::Emu) { 104 | let pbstr_ptr = emu.regs.rcx; 105 | let psz = emu.regs.rdx; 106 | let len = emu.regs.r8; 107 | 108 | log::info!( 109 | "{}** {} oleaut32!SysReAllocStringLen pbstr_ptr: 0x{:x} psz: 0x{:x} len: {}", 110 | emu.colors.light_red, 111 | emu.pos, 112 | pbstr_ptr, 113 | psz, 114 | len 115 | ); 116 | 117 | // Check if pbstr_ptr is NULL 118 | if pbstr_ptr == 0 { 119 | emu.regs.rax = 0; // Return FALSE 120 | return; 121 | } 122 | 123 | let size = (len + 1) * 2; // Size in bytes (UTF-16 characters + null terminator) 124 | let total_size = size + 8; // Add metadata size 125 | 126 | // Allocate new memory 127 | let new_base = emu 128 | .maps 129 | .alloc(total_size + 100) 130 | .expect("oleaut32!SysReAllocStringLen out of memory"); 131 | 132 | // Create new memory map 133 | let name = format!("alloc_{:x}", new_base); 134 | emu.maps.create_map(&name, new_base, total_size + 100); 135 | 136 | // Copy data from psz if it's not NULL 137 | if psz != 0 { 138 | emu.maps.memcpy(new_base + 8, psz, len as usize * 2); 139 | } 140 | 141 | // Free old string (reading old BSTR pointer from pbstr_ptr) 142 | let old_bstr = emu.maps.read_qword(pbstr_ptr).unwrap_or(0); 143 | if old_bstr != 0 { 144 | // Optional: Free the old allocation if needed 145 | // emu.maps.free(&format!("alloc_{:x}", old_bstr - 8)); 146 | } 147 | 148 | // Update the BSTR pointer 149 | emu.maps.write_qword(pbstr_ptr, new_base + 8); 150 | 151 | log::info!( 152 | "{}** {} oleaut32!SysReAllocStringLen allocated new string at 0x{:x} size: {} {}", 153 | emu.colors.light_red, 154 | emu.pos, 155 | new_base + 8, 156 | size, 157 | emu.colors.nc 158 | ); 159 | 160 | emu.regs.rax = 1; // Return TRUE for success 161 | } 162 | 163 | /* 164 | HRESULT VariantClear( 165 | [in, out] VARIANTARG *pvarg 166 | ); 167 | */ 168 | fn VariantClear(emu: &mut emu::Emu) { 169 | let pvarg = emu.regs.rcx; 170 | 171 | log::info!( 172 | "{}** {} oleaut32!VariantClear pvarg: 0x{:x} {}", 173 | emu.colors.light_red, 174 | emu.pos, 175 | pvarg, 176 | emu.colors.nc 177 | ); 178 | 179 | // TODO: do something 180 | 181 | emu.regs.rax = 0; // S_OK 182 | } 183 | -------------------------------------------------------------------------------- /libmwemu/src/winapi64/shell32.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi64; 4 | 5 | pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String { 6 | let api = winapi64::kernel32::guess_api_name(emu, addr); 7 | match api.as_str() { 8 | "RealShellExecuteA" => RealShellExecuteA(emu), 9 | _ => { 10 | if emu.cfg.skip_unimplemented == false { 11 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 12 | serialization::Serialization::dump_to_file( 13 | &emu, 14 | emu.cfg.dump_filename.as_ref().unwrap(), 15 | ); 16 | } 17 | 18 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 19 | } 20 | log::warn!( 21 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 22 | addr, 23 | api, 24 | emu.regs.rip 25 | ); 26 | return api; 27 | } 28 | } 29 | String::new() 30 | } 31 | 32 | fn RealShellExecuteA(emu: &mut emu::Emu) { 33 | let handle = emu.regs.rcx; 34 | let operation = emu.regs.rdx; 35 | let file_ptr = emu.regs.r8; 36 | let params_ptr = emu.regs.r9; 37 | let dir = emu 38 | .maps 39 | .read_qword(emu.regs.rsp + 0x20) 40 | .expect("cannot read parameter"); 41 | let bShowWindow = emu 42 | .maps 43 | .read_qword(emu.regs.rsp + 0x28) 44 | .expect("cannot read parameter"); 45 | 46 | let file = emu.maps.read_string(file_ptr); 47 | let params = emu.maps.read_string(params_ptr); 48 | 49 | log::info!( 50 | "{}** {} shell32!RealShellExecuteA {} {} {}", 51 | emu.colors.light_red, 52 | emu.pos, 53 | file, 54 | params, 55 | emu.colors.nc 56 | ); 57 | 58 | emu.regs.rax = 34; 59 | } 60 | -------------------------------------------------------------------------------- /libmwemu/src/winapi64/shlwapi.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi64; 4 | //use crate::constants; 5 | //use crate::winapi32::helper; 6 | 7 | pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String { 8 | let api = winapi64::kernel32::guess_api_name(emu, addr); 9 | match api.as_str() { 10 | "PathIsContentTypeW" => PathIsContentTypeW(emu), 11 | "PathFindSuffixArrayA" => PathFindSuffixArrayA(emu), 12 | 13 | _ => { 14 | if emu.cfg.skip_unimplemented == false { 15 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 16 | serialization::Serialization::dump_to_file( 17 | &emu, 18 | emu.cfg.dump_filename.as_ref().unwrap(), 19 | ); 20 | } 21 | 22 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 23 | } 24 | log::warn!( 25 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 26 | addr, 27 | api, 28 | emu.regs.rip 29 | ); 30 | return api; 31 | } 32 | } 33 | 34 | String::new() 35 | } 36 | 37 | pub fn PathIsContentTypeW(emu: &mut emu::Emu) { 38 | let path_ptr = emu.regs.rcx; 39 | let content_type_ptr = emu.regs.rdx; 40 | 41 | let mut path = String::new(); 42 | let mut content_type = String::new(); 43 | 44 | if path_ptr > 0 { 45 | path = emu.maps.read_wide_string(path_ptr); 46 | } 47 | if content_type_ptr > 0 { 48 | content_type = emu.maps.read_wide_string(content_type_ptr); 49 | } 50 | 51 | log::info!( 52 | "{}** {} shlwapi!PathIsContentTypeW path: {} content-type: {} {}", 53 | emu.colors.light_red, 54 | emu.pos, 55 | path, 56 | content_type, 57 | emu.colors.nc 58 | ); 59 | 60 | emu.regs.rax = 1; 61 | } 62 | 63 | pub fn PathFindSuffixArrayA(emu: &mut emu::Emu) { 64 | let path_ptr = emu.regs.rcx; 65 | let suffixes_ptr = emu.regs.rdx; 66 | 67 | let mut path = String::new(); 68 | let mut suffixes = String::new(); 69 | 70 | if path_ptr > 0 { 71 | path = emu.maps.read_string(path_ptr); 72 | } 73 | if suffixes_ptr > 0 { 74 | suffixes = emu.maps.read_string(suffixes_ptr); 75 | } 76 | 77 | log::info!( 78 | "{}** {} shlwapi!PathFindSuffixArrayA path: {} suffixes: {} {}", 79 | emu.colors.light_red, 80 | emu.pos, 81 | path, 82 | suffixes, 83 | emu.colors.nc 84 | ); 85 | 86 | emu.regs.rax = emu.regs.rdx; 87 | } 88 | -------------------------------------------------------------------------------- /libmwemu/src/winapi64/user32.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi64; 4 | 5 | pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String { 6 | let api = winapi64::kernel32::guess_api_name(emu, addr); 7 | match api.as_str() { 8 | "MessageBoxA" => MessageBoxA(emu), 9 | "GetDesktopWindow" => GetDesktopWindow(emu), 10 | "GetSystemMetrics" => GetSystemMetrics(emu), 11 | "SystemParametersInfoA" => SystemParametersInfoA(emu), 12 | "LoadIconA" => LoadIconA(emu), 13 | "LoadCursorA" => LoadCursorA(emu), 14 | "RegisterClassA" => RegisterClassA(emu), 15 | "RegisterClassW" => RegisterClassW(emu), 16 | "GetDC" => GetDC(emu), 17 | "ReleaseDC" => ReleaseDC(emu), 18 | _ => { 19 | if emu.cfg.skip_unimplemented == false { 20 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 21 | serialization::Serialization::dump_to_file( 22 | &emu, 23 | emu.cfg.dump_filename.as_ref().unwrap(), 24 | ); 25 | } 26 | 27 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 28 | } 29 | log::warn!( 30 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 31 | addr, 32 | api, 33 | emu.regs.rip 34 | ); 35 | return api; 36 | } 37 | } 38 | String::new() 39 | } 40 | 41 | fn MessageBoxA(emu: &mut emu::Emu) { 42 | let titleptr = emu.regs.rcx; 43 | let msgptr = emu.regs.rdx; 44 | let msg = emu.maps.read_string(msgptr); 45 | let title = emu.maps.read_string(titleptr); 46 | 47 | log::info!( 48 | "{}** {} user32!MessageBoxA {} {} {}", 49 | emu.colors.light_red, 50 | emu.pos, 51 | title, 52 | msg, 53 | emu.colors.nc 54 | ); 55 | 56 | emu.regs.rax = 0; 57 | } 58 | 59 | fn GetDesktopWindow(emu: &mut emu::Emu) { 60 | log::info!( 61 | "{}** {} user32!GetDesktopWindow {}", 62 | emu.colors.light_red, 63 | emu.pos, 64 | emu.colors.nc 65 | ); 66 | //emu.regs.rax = 0x11223344; // current window handle 67 | emu.regs.rax = 0; // no windows handler is more stealthy 68 | } 69 | 70 | /* 71 | int GetSystemMetrics( 72 | [in] int nIndex 73 | ); 74 | */ 75 | fn GetSystemMetrics(emu: &mut emu::Emu) { 76 | let nindex = emu.regs.rcx as usize; 77 | log::info!( 78 | "{}** {} user32!GetSystemMetrics nindex: {}{}", 79 | emu.colors.light_red, 80 | emu.pos, 81 | nindex, 82 | emu.colors.nc 83 | ); 84 | // TODO: do something 85 | emu.regs.rax = 0; 86 | } 87 | 88 | /* 89 | BOOL SystemParametersInfoA( 90 | [in] UINT uiAction, 91 | [in] UINT uiParam, 92 | [in, out] PVOID pvParam, 93 | [in] UINT fWinIni 94 | ); 95 | */ 96 | fn SystemParametersInfoA(emu: &mut emu::Emu) { 97 | let ui_action = emu.regs.rcx; 98 | let ui_param = emu.regs.rdx; 99 | let pv_param = emu.regs.r8; 100 | let f_win_ini = emu.regs.r9; 101 | log_red!( 102 | emu, 103 | "** {} user32!SystemParametersInfoA {} {} {} {}", 104 | emu.pos, 105 | ui_action, 106 | ui_param, 107 | pv_param, 108 | f_win_ini 109 | ); 110 | // TODO: write pvParam 111 | emu.regs.rax = 1; 112 | } 113 | 114 | /* 115 | HICON LoadIconA( 116 | [in, optional] HINSTANCE hInstance, 117 | [in] LPCSTR lpIconName 118 | ); 119 | */ 120 | fn LoadIconA(emu: &mut emu::Emu) { 121 | let hinstance = emu.regs.rcx; 122 | let lpiconname = emu.regs.rdx; 123 | log_red!( 124 | emu, 125 | "** {} user32!LoadIconA {} {}", 126 | emu.pos, 127 | hinstance, 128 | lpiconname 129 | ); 130 | // TODO: do not return null 131 | emu.regs.rax = 0; 132 | } 133 | 134 | /* 135 | HCURSOR LoadCursorA( 136 | [in, optional] HINSTANCE hInstance, 137 | [in] LPCSTR lpCursorName 138 | ); 139 | */ 140 | fn LoadCursorA(emu: &mut emu::Emu) { 141 | let hinstance = emu.regs.rcx; 142 | let lpcursorname = emu.regs.rdx; 143 | log_red!( 144 | emu, 145 | "** {} user32!LoadCursorA {} {}", 146 | emu.pos, 147 | hinstance, 148 | lpcursorname 149 | ); 150 | // TODO: do not return null 151 | emu.regs.rax = 0; 152 | } 153 | 154 | /* 155 | ATOM RegisterClassA( 156 | [in] const WNDCLASSA *lpWndClass 157 | ); 158 | */ 159 | fn RegisterClassA(emu: &mut emu::Emu) { 160 | let lpwndclass = emu.regs.rcx; 161 | log_red!(emu, "** {} user32!RegisterClassA {}", emu.pos, lpwndclass); 162 | // TODO: do not return null 163 | emu.regs.rax = 0; 164 | } 165 | 166 | /* 167 | ATOM RegisterClassW( 168 | [in] const WNDCLASSW *lpWndClass 169 | ); 170 | */ 171 | fn RegisterClassW(emu: &mut emu::Emu) { 172 | let lpwndclass = emu.regs.rcx; 173 | log_red!(emu, "** {} user32!RegisterClassW {}", emu.pos, lpwndclass); 174 | // TODO: do not return null 175 | emu.regs.rax = 0; 176 | } 177 | 178 | /* 179 | HDC GetDC( 180 | [in] HWND hWnd 181 | ); 182 | */ 183 | fn GetDC(emu: &mut emu::Emu) { 184 | let hwnd = emu.regs.rcx; 185 | log_red!(emu, "** {} user32!GetDC {}", emu.pos, hwnd); 186 | // TODO: do something / do not return null 187 | emu.regs.rax = 0; 188 | } 189 | 190 | /* 191 | int ReleaseDC( 192 | [in] HWND hWnd, 193 | [in] HDC hDC 194 | ); 195 | */ 196 | fn ReleaseDC(emu: &mut emu::Emu) { 197 | let hwnd = emu.regs.rcx; 198 | let hdc = emu.regs.rdx; 199 | log_red!(emu, "** {} user32!ReleaseDC {} {}", emu.pos, hwnd, hdc); 200 | // TODO: do something 201 | emu.regs.rax = 1; 202 | } 203 | -------------------------------------------------------------------------------- /libmwemu/src/winapi64/uxtheme.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi64; 4 | 5 | pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String { 6 | let api = winapi64::kernel32::guess_api_name(emu, addr); 7 | match api.as_str() { 8 | "IsAppThemed" => IsAppThemed(emu), 9 | "IsThemeActive" => IsThemeActive(emu), 10 | "GetThemeAppProperties" => GetThemeAppProperties(emu), 11 | _ => { 12 | if emu.cfg.skip_unimplemented == false { 13 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 14 | serialization::Serialization::dump_to_file( 15 | &emu, 16 | emu.cfg.dump_filename.as_ref().unwrap(), 17 | ); 18 | } 19 | 20 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 21 | } 22 | log::warn!( 23 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 24 | addr, 25 | api, 26 | emu.regs.rip 27 | ); 28 | return api; 29 | } 30 | } 31 | String::new() 32 | } 33 | 34 | fn IsAppThemed(emu: &mut emu::Emu) { 35 | log_red!(emu, "** {} uxtheme!IsAppThemed", emu.pos); 36 | emu.regs.rax = 1; 37 | } 38 | 39 | fn IsThemeActive(emu: &mut emu::Emu) { 40 | log_red!(emu, "** {} uxtheme!IsThemeActive", emu.pos); 41 | emu.regs.rax = 1; 42 | } 43 | 44 | fn GetThemeAppProperties(emu: &mut emu::Emu) { 45 | log_red!(emu, "** {} uxtheme!GetThemeAppProperties", emu.pos); 46 | emu.regs.rax = 1; 47 | } 48 | -------------------------------------------------------------------------------- /libmwemu/src/winapi64/winhttp.rs: -------------------------------------------------------------------------------- 1 | use crate::emu; 2 | use crate::serialization; 3 | use crate::winapi64; 4 | 5 | pub fn gateway(addr: u64, emu: &mut emu::Emu) -> String { 6 | let api = winapi64::kernel32::guess_api_name(emu, addr); 7 | match api.as_str() { 8 | _ => { 9 | if emu.cfg.skip_unimplemented == false { 10 | if emu.cfg.dump_on_exit && emu.cfg.dump_filename.is_some() { 11 | serialization::Serialization::dump_to_file( 12 | &emu, 13 | emu.cfg.dump_filename.as_ref().unwrap(), 14 | ); 15 | } 16 | 17 | unimplemented!("atemmpt to call unimplemented API 0x{:x} {}", addr, api); 18 | } 19 | log::warn!( 20 | "calling unimplemented API 0x{:x} {} at 0x{:x}", 21 | addr, 22 | api, 23 | emu.regs.rip 24 | ); 25 | return api; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /maps32/RstrtMgr.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/RstrtMgr.dll -------------------------------------------------------------------------------- /maps32/WINSPOOL.DRV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/WINSPOOL.DRV -------------------------------------------------------------------------------- /maps32/advapi32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/advapi32.dll -------------------------------------------------------------------------------- /maps32/api-ms-win-crt-environment-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/api-ms-win-crt-environment-l1-1-0.dll -------------------------------------------------------------------------------- /maps32/api-ms-win-crt-heap-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/api-ms-win-crt-heap-l1-1-0.dll -------------------------------------------------------------------------------- /maps32/api-ms-win-crt-locale-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/api-ms-win-crt-locale-l1-1-0.dll -------------------------------------------------------------------------------- /maps32/api-ms-win-crt-math-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/api-ms-win-crt-math-l1-1-0.dll -------------------------------------------------------------------------------- /maps32/api-ms-win-crt-private-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/api-ms-win-crt-private-l1-1-0.dll -------------------------------------------------------------------------------- /maps32/api-ms-win-crt-runtime-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/api-ms-win-crt-runtime-l1-1-0.dll -------------------------------------------------------------------------------- /maps32/api-ms-win-crt-stdio-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/api-ms-win-crt-stdio-l1-1-0.dll -------------------------------------------------------------------------------- /maps32/bcrypt.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/bcrypt.dll -------------------------------------------------------------------------------- /maps32/combase.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/combase.dll -------------------------------------------------------------------------------- /maps32/comctl.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/comctl.dll -------------------------------------------------------------------------------- /maps32/comctl32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/comctl32.dll -------------------------------------------------------------------------------- /maps32/comdlg32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/comdlg32.dll -------------------------------------------------------------------------------- /maps32/crypt32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/crypt32.dll -------------------------------------------------------------------------------- /maps32/d3d11.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/d3d11.dll -------------------------------------------------------------------------------- /maps32/dbghelp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/dbghelp.dll -------------------------------------------------------------------------------- /maps32/dnsapi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/dnsapi.dll -------------------------------------------------------------------------------- /maps32/esent.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/esent.dll -------------------------------------------------------------------------------- /maps32/gdi32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/gdi32.dll -------------------------------------------------------------------------------- /maps32/gdiplus.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/gdiplus.dll -------------------------------------------------------------------------------- /maps32/iphlpapi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/iphlpapi.dll -------------------------------------------------------------------------------- /maps32/kernel32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/kernel32.dll -------------------------------------------------------------------------------- /maps32/kernelbase.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/kernelbase.dll -------------------------------------------------------------------------------- /maps32/libgcc_s_dw2-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/libgcc_s_dw2-1.dll -------------------------------------------------------------------------------- /maps32/loader.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/loader.exe -------------------------------------------------------------------------------- /maps32/lz32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/lz32.dll -------------------------------------------------------------------------------- /maps32/m10000.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/m10000.bin -------------------------------------------------------------------------------- /maps32/m20000.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/m20000.bin -------------------------------------------------------------------------------- /maps32/mpr.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/mpr.dll -------------------------------------------------------------------------------- /maps32/mscoree.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/mscoree.dll -------------------------------------------------------------------------------- /maps32/msvcp140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/msvcp140.dll -------------------------------------------------------------------------------- /maps32/msvcp_win.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/msvcp_win.dll -------------------------------------------------------------------------------- /maps32/msvcrt.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/msvcrt.dll -------------------------------------------------------------------------------- /maps32/netapi32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/netapi32.dll -------------------------------------------------------------------------------- /maps32/noname.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/noname.dll -------------------------------------------------------------------------------- /maps32/nsi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/nsi.dll -------------------------------------------------------------------------------- /maps32/ntdll.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/ntdll.dll -------------------------------------------------------------------------------- /maps32/ole32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/ole32.dll -------------------------------------------------------------------------------- /maps32/oleacc.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/oleacc.dll -------------------------------------------------------------------------------- /maps32/oleaut32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/oleaut32.dll -------------------------------------------------------------------------------- /maps32/olepro32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/olepro32.dll -------------------------------------------------------------------------------- /maps32/psapi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/psapi.dll -------------------------------------------------------------------------------- /maps32/pstorec.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/pstorec.dll -------------------------------------------------------------------------------- /maps32/rasapi32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/rasapi32.dll -------------------------------------------------------------------------------- /maps32/shell32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/shell32.dll -------------------------------------------------------------------------------- /maps32/shlwapi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/shlwapi.dll -------------------------------------------------------------------------------- /maps32/ucrtbase.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/ucrtbase.dll -------------------------------------------------------------------------------- /maps32/user32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/user32.dll -------------------------------------------------------------------------------- /maps32/userenv.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/userenv.dll -------------------------------------------------------------------------------- /maps32/usp10.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/usp10.dll -------------------------------------------------------------------------------- /maps32/uxtheme.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/uxtheme.dll -------------------------------------------------------------------------------- /maps32/vaultcli.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/vaultcli.dll -------------------------------------------------------------------------------- /maps32/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/vcruntime140.dll -------------------------------------------------------------------------------- /maps32/version.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/version.dll -------------------------------------------------------------------------------- /maps32/vtcheck.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import time 3 | import sys 4 | 5 | API_KEY = "141adc1db02b7d093787791cb3e18aea2b864dac99010bbad689e61db82a92b3" # Reemplázalo con tu clave de la API de VirusTotal 6 | INPUT_FILE = sys.argv[1] # Archivo con los hashes 7 | OUTPUT_FILE = "results.txt" # Salida con los resultados 8 | VT_URL = "https://www.virustotal.com/api/v3/files/{}" 9 | 10 | def get_virus_total_report(hash_md5): 11 | headers = { 12 | "x-apikey": API_KEY 13 | } 14 | response = requests.get(VT_URL.format(hash_md5), headers=headers) 15 | 16 | if response.status_code == 200: 17 | data = response.json() 18 | return data['data']['attributes']['last_analysis_stats']['malicious'] 19 | elif response.status_code == 404: 20 | return "Not Found" 21 | else: 22 | return f"Error {response.status_code}" 23 | 24 | def main(): 25 | with open(INPUT_FILE, "r") as infile, open(OUTPUT_FILE, "w") as outfile: 26 | for line in infile: 27 | line = line.strip() 28 | if not line: 29 | continue 30 | 31 | parts = line.split() 32 | if len(parts) >= 1: 33 | hash_md5 = parts[0] 34 | filename = parts[1] if len(parts) > 1 else "N/A" 35 | 36 | print(f"Checking hash: {hash_md5} ({filename})") 37 | detections = get_virus_total_report(hash_md5) 38 | outfile.write(f"{hash_md5} {filename} {detections}\n") 39 | print(f"{hash_md5} -> {detections} detections") 40 | 41 | time.sleep(16) # Evita exceder el límite de la API gratuita (4 por minuto) 42 | print("Results saved to:", OUTPUT_FILE) 43 | 44 | if __name__ == "__main__": 45 | main() 46 | -------------------------------------------------------------------------------- /maps32/winhttp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/winhttp.dll -------------------------------------------------------------------------------- /maps32/wininet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/wininet.dll -------------------------------------------------------------------------------- /maps32/winmm.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/winmm.dll -------------------------------------------------------------------------------- /maps32/winspool.drv.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/winspool.drv.dll -------------------------------------------------------------------------------- /maps32/wintrust.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/wintrust.dll -------------------------------------------------------------------------------- /maps32/ws2_32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/ws2_32.dll -------------------------------------------------------------------------------- /maps32/wsock32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps32/wsock32.dll -------------------------------------------------------------------------------- /maps64/advapi32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/advapi32.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-crt-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-crt-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-crt-l2-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-crt-l2-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-delayload-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-delayload-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-delayload-l1-1-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-delayload-l1-1-1.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-errorhandling-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-errorhandling-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-file-l1-2-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-file-l1-2-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-file-l2-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-file-l2-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-handle-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-handle-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-heap-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-heap-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-heap-l2-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-heap-l2-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-heap-obsolete-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-heap-obsolete-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-io-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-io-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-libraryloader-l1-2-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-libraryloader-l1-2-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-localization-l1-2-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-localization-l1-2-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-memory-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-memory-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-processthreads-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-processthreads-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-processthreads-l1-1-1.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-processthreads-l1-1-1.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-profile-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-profile-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-registry-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-registry-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-string-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-string-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-synch-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-synch-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-synch-l1-2-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-synch-l1-2-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-sysinfo-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-sysinfo-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-timezone-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-timezone-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-util-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-util-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-core-xstate-l2-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-core-xstate-l2-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-crt-conio-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-crt-conio-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-crt-convert-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-crt-convert-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-crt-environment-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-crt-environment-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-crt-filesystem-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-crt-filesystem-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-crt-heap-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-crt-heap-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-crt-locale-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-crt-locale-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-crt-math-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-crt-math-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-crt-multibyte-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-crt-multibyte-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-crt-private-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-crt-private-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-crt-process-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-crt-process-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-crt-runtime-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-crt-runtime-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-crt-stdio-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-crt-stdio-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-crt-string-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-crt-string-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-crt-time-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-crt-time-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-crt-utility-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-crt-utility-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-eventing-classicprovider-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-eventing-classicprovider-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-eventing-provider-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-eventing-provider-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-security-base-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-security-base-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/api-ms-win-security-credentials-l1-1-0.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/api-ms-win-security-credentials-l1-1-0.dll -------------------------------------------------------------------------------- /maps64/avifil32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/avifil32.dll -------------------------------------------------------------------------------- /maps64/bcrypt.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/bcrypt.dll -------------------------------------------------------------------------------- /maps64/bcryptprimitives.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/bcryptprimitives.dll -------------------------------------------------------------------------------- /maps64/cabinet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/cabinet.dll -------------------------------------------------------------------------------- /maps64/combase.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/combase.dll -------------------------------------------------------------------------------- /maps64/comctl32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/comctl32.dll -------------------------------------------------------------------------------- /maps64/dnsapi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/dnsapi.dll -------------------------------------------------------------------------------- /maps64/dwmapi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/dwmapi.dll -------------------------------------------------------------------------------- /maps64/gdi32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/gdi32.dll -------------------------------------------------------------------------------- /maps64/iphlpapi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/iphlpapi.dll -------------------------------------------------------------------------------- /maps64/kernel.appcore.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/kernel.appcore.dll -------------------------------------------------------------------------------- /maps64/kernel32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/kernel32.dll -------------------------------------------------------------------------------- /maps64/kernelbase.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/kernelbase.dll -------------------------------------------------------------------------------- /maps64/linker.bin_prev: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/linker.bin_prev -------------------------------------------------------------------------------- /maps64/linux_dynamic_stack.bin.old: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/linux_dynamic_stack.bin.old -------------------------------------------------------------------------------- /maps64/loader.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/loader.exe -------------------------------------------------------------------------------- /maps64/m10000.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/m10000.bin -------------------------------------------------------------------------------- /maps64/m20000.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/m20000.bin -------------------------------------------------------------------------------- /maps64/m520000.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/m520000.bin -------------------------------------------------------------------------------- /maps64/mpr.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/mpr.dll -------------------------------------------------------------------------------- /maps64/mscoree.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/mscoree.dll -------------------------------------------------------------------------------- /maps64/msctf.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/msctf.dll -------------------------------------------------------------------------------- /maps64/msimg32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/msimg32.dll -------------------------------------------------------------------------------- /maps64/msvcp140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/msvcp140.dll -------------------------------------------------------------------------------- /maps64/msvcrt.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/msvcrt.dll -------------------------------------------------------------------------------- /maps64/mswsock.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/mswsock.dll -------------------------------------------------------------------------------- /maps64/netapi32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/netapi32.dll -------------------------------------------------------------------------------- /maps64/ntdll.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/ntdll.dll -------------------------------------------------------------------------------- /maps64/ole32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/ole32.dll -------------------------------------------------------------------------------- /maps64/oleaut32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/oleaut32.dll -------------------------------------------------------------------------------- /maps64/profapi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/profapi.dll -------------------------------------------------------------------------------- /maps64/psapi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/psapi.dll -------------------------------------------------------------------------------- /maps64/rpcrt4.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/rpcrt4.dll -------------------------------------------------------------------------------- /maps64/secur32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/secur32.dll -------------------------------------------------------------------------------- /maps64/shell32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/shell32.dll -------------------------------------------------------------------------------- /maps64/shfolder.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/shfolder.dll -------------------------------------------------------------------------------- /maps64/shlwapi.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/shlwapi.dll -------------------------------------------------------------------------------- /maps64/teb.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/teb.bin -------------------------------------------------------------------------------- /maps64/user32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/user32.dll -------------------------------------------------------------------------------- /maps64/userenv.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/userenv.dll -------------------------------------------------------------------------------- /maps64/uxtheme.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/uxtheme.dll -------------------------------------------------------------------------------- /maps64/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/vcruntime140.dll -------------------------------------------------------------------------------- /maps64/version.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/version.dll -------------------------------------------------------------------------------- /maps64/windows.storage.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/windows.storage.dll -------------------------------------------------------------------------------- /maps64/winhttp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/winhttp.dll -------------------------------------------------------------------------------- /maps64/wininet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/wininet.dll -------------------------------------------------------------------------------- /maps64/winmm.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/winmm.dll -------------------------------------------------------------------------------- /maps64/wintypes.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/wintypes.dll -------------------------------------------------------------------------------- /maps64/ws2_32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/ws2_32.dll -------------------------------------------------------------------------------- /maps64/wtsapi32.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/maps64/wtsapi32.dll -------------------------------------------------------------------------------- /mwemu/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .gitconfig 3 | shellcodes32/ 4 | shellcodes64/ 5 | .DS_Store 6 | x 7 | *.swp 8 | *.idb 9 | test/ 10 | scripts/mwemu-output.txt 11 | scripts/mwemu-errors.json 12 | scripts/node_modules/ 13 | Cargo.lock 14 | -------------------------------------------------------------------------------- /mwemu/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mwemu" 3 | version = "0.7.10" 4 | authors = ["sha0coder"] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | clap = "2.33.3" 11 | log = "0.4.22" 12 | env_logger = "0.11.6" 13 | libmwemu = { path = "../libmwemu" } 14 | -------------------------------------------------------------------------------- /pics/basic_shellcode1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/basic_shellcode1.png -------------------------------------------------------------------------------- /pics/basic_shellcode2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/basic_shellcode2.png -------------------------------------------------------------------------------- /pics/cobalt_strike.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/cobalt_strike.png -------------------------------------------------------------------------------- /pics/console_help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/console_help.png -------------------------------------------------------------------------------- /pics/exception.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/exception.png -------------------------------------------------------------------------------- /pics/guloader1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/guloader1.png -------------------------------------------------------------------------------- /pics/maps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/maps.png -------------------------------------------------------------------------------- /pics/memdump.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/memdump.png -------------------------------------------------------------------------------- /pics/metasploit_api_loader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/metasploit_api_loader.png -------------------------------------------------------------------------------- /pics/metasploit_rshell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/metasploit_rshell.png -------------------------------------------------------------------------------- /pics/msf_encoded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/msf_encoded.png -------------------------------------------------------------------------------- /pics/msgbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/msgbox.png -------------------------------------------------------------------------------- /pics/mwemu_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/mwemu_logo.png -------------------------------------------------------------------------------- /pics/shikata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/shikata.png -------------------------------------------------------------------------------- /pics/structure3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/structure3.png -------------------------------------------------------------------------------- /pics/structures.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/structures.png -------------------------------------------------------------------------------- /pics/structures2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/structures2.png -------------------------------------------------------------------------------- /pics/usage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pics/usage.png -------------------------------------------------------------------------------- /pymwemu/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | .pytest_cache/ 6 | *.py[cod] 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | .venv/ 14 | env/ 15 | .env/ 16 | bin/ 17 | build/ 18 | develop-eggs/ 19 | dist/ 20 | eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | include/ 27 | man/ 28 | venv/ 29 | *.egg-info/ 30 | .installed.cfg 31 | *.egg 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | pip-selfcheck.json 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | 46 | # Translations 47 | *.mo 48 | 49 | # Mr Developer 50 | .mr.developer.cfg 51 | .project 52 | .pydevproject 53 | 54 | # Rope 55 | .ropeproject 56 | 57 | # Django stuff: 58 | *.log 59 | *.pot 60 | 61 | .DS_Store 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyCharm 67 | .idea/ 68 | 69 | # VSCode 70 | .vscode/ 71 | 72 | # Pyenv 73 | .python-version 74 | -------------------------------------------------------------------------------- /pymwemu/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pymwemu" 3 | version = "0.9.12" 4 | edition = "2021" 5 | description = "x86 32/64bits and system internals emulator, for securely emulating malware and other stuff." 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | [lib] 9 | name = "pymwemu" 10 | crate-type = ["cdylib"] 11 | 12 | [dependencies] 13 | pyo3 = "0.18.1" 14 | env_logger = "0.11.6" 15 | libmwemu = { path = "../libmwemu" } 16 | log = "0.4.22" 17 | iced-x86 = "1.21.0" 18 | -------------------------------------------------------------------------------- /pymwemu/__init__.py: -------------------------------------------------------------------------------- 1 | from .pymwemu import * 2 | 3 | __doc__ = pymwemu.__doc__ 4 | if hasattr(pymwemu, "__all__"): 5 | __all__ = pymwemu.__all__ 6 | -------------------------------------------------------------------------------- /pymwemu/examples/danabot_rsa.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "abba969b-d0b4-452a-96ff-24e13d7dabed", 6 | "metadata": {}, 7 | "source": [ 8 | "## Emulating Danabot RSA keypair" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": null, 14 | "id": "71999e76-6823-4f68-b6ad-5dcf1f5f386a", 15 | "metadata": { 16 | "tags": [] 17 | }, 18 | "outputs": [], 19 | "source": [ 20 | "import pymwemu\n", 21 | "\n", 22 | "emu = pymwemu.init32()\n", 23 | "emu.load_maps('/home/sha0/src/mwemu/maps32/')\n", 24 | "emu.load_binary('/home/sha0/samples/danabot/2023-04-03-MainModule/unpacked2/dbmm_unpacked.dll')\n", 25 | "emu.set_verbose(3)\n", 26 | "emu.set_base_address(0x1E70000)\n", 27 | "emu.enable_banzai_mode()\n", 28 | "rsa_keygen = 0x022EBBC0 \n", 29 | "\n", 30 | "\n", 31 | "public_key_ptr = emu.alloc(\"pubkey\", 1024)\n", 32 | "private_key_ptr = emu.alloc(\"privkey\", 1024)\n", 33 | "pub_ptr = emu.alloc(\"pub_ptr\", 4)\n", 34 | "priv_ptr = emu.alloc(\"priv_ptr\", 4)\n", 35 | "\n", 36 | "emu.write_dword(pub_ptr, public_key_ptr)\n", 37 | "emu.write_dword(priv_ptr, private_key_ptr)\n", 38 | "\n", 39 | "emu.enable_trace_reg(['eax'])\n", 40 | "\n", 41 | "emu.set_reg('eax', pub_ptr)\n", 42 | "emu.set_reg('edx', priv_ptr)\n", 43 | "\n", 44 | "\n", 45 | "emu.call(rsa_keygen,[priv_ptr, pub_ptr])\n" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": null, 51 | "id": "77cfab8c-f385-4d95-a3e5-c2a0455a0ea8", 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": null, 59 | "id": "83c45d63-a00b-4f43-b9fe-9137f5c0f94b", 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [] 63 | } 64 | ], 65 | "metadata": { 66 | "kernelspec": { 67 | "display_name": "Python 3", 68 | "language": "python", 69 | "name": "python3" 70 | }, 71 | "language_info": { 72 | "codemirror_mode": { 73 | "name": "ipython", 74 | "version": 3 75 | }, 76 | "file_extension": ".py", 77 | "mimetype": "text/x-python", 78 | "name": "python", 79 | "nbconvert_exporter": "python", 80 | "pygments_lexer": "ipython3", 81 | "version": "3.9.2" 82 | } 83 | }, 84 | "nbformat": 4, 85 | "nbformat_minor": 5 86 | } 87 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/.ipynb_checkpoints/test-checkpoint.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sha0coder/mwemu/4b9f3ea3e427a911e15c5899136badeccc3bc3a7/pymwemu/examples/scripts/.ipynb_checkpoints/test-checkpoint.py -------------------------------------------------------------------------------- /pymwemu/examples/scripts/api_implementation.py: -------------------------------------------------------------------------------- 1 | ''' 2 | pymwemu is synchronous, if you need to implement an unimplemented api 3 | or override an implemented api can use emu.run_until_apicall() in a loop 4 | ''' 5 | 6 | import pymwemu 7 | import sys 8 | 9 | emu = pymwemu.init32() 10 | emu.load_maps('/home/sha0/src/mwemu/maps32/') 11 | emu.load_binary('/home/sha0/src/mwemu/shellcodes32/shikata.bin') 12 | 13 | 14 | 15 | while True: 16 | api = emu.run_until_apicall() # stop until next apicall try 17 | print(f'calling api 0x{api:x}') 18 | 19 | if api == 0x77486b0e: 20 | # override recv implementation here 21 | esp = emu.get_reg('esp') 22 | ret_addr = emu.read_dword(esp) 23 | socket = emu.read_dword(esp+4) 24 | buff = emu.read_dword(esp+8) 25 | sz = emu.read_dword(esp+12) 26 | flags = emu.read_dword(esp+16) 27 | print(f'recv {socket} 0x{buff:x} {sz} {flags}') 28 | emu.write_buffer(buff, b'\x11\x22\x33\x44') 29 | emu.set_reg('eax', 4) 30 | #emu.set_eip(api) # triger emulators api implementation 31 | emu.set_eip(ret_addr) # dont trigger emulation api inmplementation 32 | break 33 | 34 | else: 35 | emu.set_eip(api) # trigger api implementation on emulator 36 | 37 | 38 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/danabot_crypto.py: -------------------------------------------------------------------------------- 1 | import pymwemu 2 | import sys 3 | 4 | emu = pymwemu.init32() 5 | emu.load_maps('/home/sha0/src/mwemu/maps32/') 6 | emu.load_binary('/home/sha0/src/demo/mw/dbmm_unpacked.dll') 7 | emu.enable_banzai_mode() 8 | 9 | danabot_crypt_decrypt_aes256 = 0x022D61B8 10 | 11 | pt = emu.alloc("pt", 1024)+8 12 | emu.write_string(pt, "lskdfñalsdf") 13 | 14 | pubkey = emu.alloc("pubkey", 1024)+8 15 | emu.write_spaced_bytes(pubkey, "AA BB 3F 1B 2C") 16 | 17 | seed = emu.alloc("seed", 100)+8 18 | emu.write_string(seed, "lksdjfasdf") 19 | 20 | 21 | emu.set_reg("eax", 1) 22 | emu.set_reg("edx", pt) 23 | emu.set_reg("ecx", pubkey) 24 | 25 | emu.set_verbose(3) 26 | emu.call32( danabot_crypt_decrypt_aes256, [seed] ) 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/danabot_extract.py: -------------------------------------------------------------------------------- 1 | import pymwemu 2 | 3 | emu = pymwemu.init32() 4 | emu.load_maps('/home/sha0/src/mwemu/maps32/') 5 | emu.load_binary('mw/dbmm_unpacked.dll') 6 | emu.disable_ctrlc() 7 | emu.set_verbose(3) 8 | 9 | 10 | 11 | def dword2ip(dword): 12 | byte1 = (dword >> 24) & 0xff 13 | byte2 = (dword >> 16) & 0xff 14 | byte3 = (dword >> 8) & 0xff 15 | byte4 = dword & 0xff 16 | ip_address = "{}.{}.{}.{}".format(byte1, byte2, byte3, byte4) 17 | return ip_address 18 | 19 | 20 | cfg = emu.alloc("static_config", 1024) 21 | 22 | 23 | emu.set_reg('ebx', cfg) 24 | for addr in emu.search_spaced_bytes_in_all("C7 43 18 40 7E 05 00"): 25 | #emu.disassemble(addr, 10) 26 | emu.set_reg('eip', addr) 27 | for i in range(9): 28 | emu.step() 29 | print('command and control hosts:') 30 | print(dword2ip(emu.read_dword(cfg+0x6a))) 31 | print(dword2ip(emu.read_dword(cfg+0x72))) 32 | print(dword2ip(emu.read_dword(cfg+0x7a))) 33 | print(dword2ip(emu.read_dword(cfg+0x82))) 34 | 35 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/danabot_get_string_emu.py: -------------------------------------------------------------------------------- 1 | import pymwemu 2 | import sys 3 | 4 | emu = pymwemu.init32() 5 | emu.load_maps('/home/sha0/src/mwemu/maps32/') 6 | emu.load_binary('/home/sha0/samples/danabot/2023-04-03-Botnet3-MainModule/unpacked2/dbmm_unpacked.dll') 7 | 8 | 9 | danabot_get_string = 0x01E7AF08 10 | 11 | i = 0 12 | while True: 13 | i += 1 14 | emu.set_reg('eax', i) 15 | s_ptr = emu.call32( danabot_get_string, [] ) 16 | try: 17 | derref = emu.read_wide_string(s_ptr) 18 | if len(derref) > 2: 19 | print(f'{i} {len(derref)} {derref}') 20 | i += (len(derref)*2) 21 | except: 22 | pass 23 | 24 | 25 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/danabot_int_deobfus_emu.py: -------------------------------------------------------------------------------- 1 | import pymwemu 2 | 3 | emu = pymwemu.init32() 4 | emu.load_maps('/home/sha0/src/mwemu/maps32/') 5 | emu.load_binary('mw/rundll32_danabotX.dll_1650000_x86.dll') 6 | emu.set_verbose(3) 7 | 8 | danabot_int_obfuscation = 0x0184ED18 9 | 10 | emu.set_reg('eax', 65833) 11 | calc = emu.call32( danabot_int_obfuscation, [] ) 12 | 13 | print(calc) 14 | 15 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/emu_pwer.py: -------------------------------------------------------------------------------- 1 | import pymwemu 2 | import sys 3 | 4 | 5 | emu = pymwemu.init32() 6 | emu.load_maps('/home/sha0/src/mwemu/maps32/') 7 | 8 | # dont load the pe, its tricked to crash the loader 9 | # instead read it to an buffer inside the emulator: 10 | x = open('pwer','rb').read() 11 | code_buffer = emu.alloc("code", len(x)) 12 | emu.write_bytes(code_buffer, x) 13 | 14 | # starting point 15 | pattern = b'\xd9\xcc\xd9\x74\x24\xf4\x58' # fpu 16 | 17 | # locating starting point 18 | off = x.find(pattern) 19 | if off < 0: 20 | print('pattern not found') 21 | sys.exit(1) 22 | 23 | # go go go 24 | emu.set_reg('eip', code_buffer + off) 25 | emu.run() 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/emu_rat.py: -------------------------------------------------------------------------------- 1 | from unsigned import Unsigned32 as u32 2 | import pymwemu 3 | import sys 4 | 5 | emu = pymwemu.init64() 6 | emu.load_maps('/Users/jesus/src/mwemu/maps64/') 7 | emu.load_binary('msedge_exe_PID1530_codechunk_225DB910000_x64.dll') 8 | 9 | 10 | comm_protocol = 0x225db9138e0 11 | 12 | emu.set_verbose(0) 13 | count = 0 14 | 15 | def encode_command(number, increment=3): 16 | byte_array = number.to_bytes((number.bit_length() + 7) // 8 or 1, byteorder='big') 17 | transformed_bytes = bytes((b + increment) & 0xFF for b in byte_array) 18 | return int.from_bytes(transformed_bytes, byteorder='big') 19 | 20 | 21 | def GetUserNameA(): 22 | retaddr = emu.stack_pop64() 23 | print('GetUserNameA') 24 | emu.write_string(emu.get_reg('rcx'), 'baremetal\x00') 25 | emu.write_qword(emu.get_reg('rdx'), 9) 26 | emu.set_reg('rax', emu.get_reg('rcx')) 27 | 28 | def recv(): 29 | global is_first 30 | retaddr = emu.stack_pop64() 31 | rip = emu.get_reg('rip') 32 | rcx = emu.get_reg('rcx') 33 | rdx = emu.get_reg('rdx') 34 | r8 = emu.get_reg('r8') 35 | cmd = 0x03030305 36 | print(f'{rip:x}: recv({rcx}, {rdx:x}, {r8}) --> {cmd}') 37 | emu.write_dword(rdx, cmd) 38 | emu.set_reg('rax', 4) 39 | 40 | def send(): 41 | retaddr = emu.stack_pop64() 42 | rip = emu.get_reg('rip') 43 | rcx = emu.get_reg('rcx') 44 | rdx = emu.get_reg('rdx') 45 | r8 = emu.get_reg('r8') 46 | content = emu.read_bytes(rdx, r8) 47 | print(f'{rip:x}: send({rcx}, {rdx:x}, {r8}) --> {content}') 48 | emu.set_reg('rax', r8) 49 | 50 | emu.set_reg('rip', comm_protocol) 51 | while True: 52 | addr, name = emu.run_until_apicall() 53 | if name == 'getusernamea': 54 | GetUserNameA() 55 | elif name =='recv': 56 | recv() 57 | elif name == 'send': 58 | send() 59 | elif name == 'shutdown': 60 | sys.exit(1) 61 | else: 62 | emu.handle_winapi(addr) 63 | 64 | 65 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/gozi_decryptbss_emu.py: -------------------------------------------------------------------------------- 1 | import pymwemu 2 | import sys 3 | 4 | emu = pymwemu.init32() 5 | emu.load_maps('/home/sha0/src/mwemu/maps32/') # Load 32bits dependncies: kernel32, winnet etc 6 | emu.load_binary('../modules/gozi_main_module.bin') # PE32 load 7 | 8 | 9 | 10 | 11 | #dll = emu.load_map('dll_hdr', 'gozi_main_module.bin', 1) 12 | # load disk file to emulator memory 13 | 14 | gozi_start = 0x1001B728 # function called from DllMain 15 | hInstDll = 0x10000000 # gozi base address 16 | lpReserved = 0 17 | 18 | 19 | # skip unimplemented apis, and continue emulation thanks to knowing the number of params. 20 | emu.enable_banzai_mode() 21 | emu.banzai_add('ConvertStringSecurityDescriptorToSecurityDescriptorA', 4) 22 | emu.banzai_add('_strupr', 1) 23 | emu.banzai_add('NtOpenProcess', 4) 24 | emu.banzai_add('NtOpenProcessToken', 3) 25 | emu.banzai_add('NtQueryInformationToken', 5) 26 | emu.banzai_add('memcpy', 3) 27 | emu.banzai_add('IsWow64Process', 2) 28 | emu.banzai_add('lstrcpy', 3) 29 | 30 | ''' 31 | # calculating key 32 | emu.set_verbose(3) 33 | emu.stack_push32(lpReserved) 34 | emu.stack_push32(hInstDll) 35 | emu.stack_push32(1) 36 | emu.set_reg('eip', gozi_start) 37 | emu.run(0x1001a550) 38 | emu.spawn_console() 39 | ''' 40 | 41 | 42 | # Decrypt BSS 43 | 44 | emu.set_verbose(3) 45 | try: 46 | emu.call32(gozi_start, [hInstDll, lpReserved]) 47 | except: 48 | pass 49 | 50 | 51 | # dump BSS 52 | 53 | print() 54 | print('First and bigger alloc is bss decrypted:') 55 | emu.show_allocs() 56 | emu.save_all_allocs('/tmp/') 57 | print('allocs saved to /tmp/') 58 | emu.spawn_console() 59 | sys.exit(1) 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/gozi_dga.py: -------------------------------------------------------------------------------- 1 | import pymwemu 2 | import random 3 | 4 | emu = pymwemu.init64() 5 | emu.load_maps('/home/sha0/src/mwemu/maps64/') 6 | emu.set_base_address(0x280000000) 7 | emu.load_binary('gozi10008.bin') 8 | emu.set_verbose(0) 9 | 10 | gozi_dga = 0x2800046A8 # function 11 | size = 10 12 | seed = 0x246640bb 13 | 14 | # write seed global 15 | emu.write_dword(0x280052D40, seed) 16 | 17 | 18 | for i in range(0,100): 19 | rax = emu.call64(gozi_dga, [size]) 20 | print(emu.read_string(rax)) 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/raccoon_strings.py: -------------------------------------------------------------------------------- 1 | import pymwemu 2 | import sys 3 | 4 | emu = pymwemu.init32() 5 | emu.load_maps('/home/sha0/src/mwemu/maps32/') 6 | emu.load_binary('mw/raccoon.bin') 7 | 8 | 9 | raccoon_decrypt_strings = 0x0404924 10 | 11 | emu.set_verbose(2) 12 | #emu.spawn_console_at_pos(6) 13 | #emu.enable_console() 14 | 15 | 16 | strings = [] 17 | 18 | emu.set_reg('eip', raccoon_decrypt_strings) 19 | while emu.step(): 20 | 21 | if emu.get_reg('eip') >= 0x040b488: 22 | break 23 | 24 | opcode = emu.read_byte(emu.get_reg('eip')) 25 | if opcode == 0x6a: # emu.get_prev_mnemonic() 26 | decrypted_ptr = emu.get_reg('eax') 27 | decrypted = emu.read_string(decrypted_ptr) 28 | strings.append(f'{hex(decrypted_ptr)}: {decrypted}') 29 | 30 | 31 | for s in list(set(strings)): 32 | if s: 33 | print(s) 34 | 35 | #emu.show_allocs() 36 | 37 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/ssl_key128_gen.py: -------------------------------------------------------------------------------- 1 | ''' 2 | ssl 1024*4 harcoded blob xored with 4 bytes generating 128 bytes. 3 | ''' 4 | 5 | 6 | import pymwemu 7 | 8 | emu = pymwemu.init32() 9 | emu.load_maps('/home/sha0/src/mwemu/maps32') 10 | emu.load_binary('mw/dbmm_unpacked.dll') 11 | emu.set_verbose(0) 12 | #emu.enable_banzai_mode() 13 | 14 | gen = emu.alloc("generated", 128) 15 | seed = emu.alloc("seed", 100) 16 | 17 | 18 | ssl_key128_gen = 0x020EDE54 19 | 20 | emu.write_spaced_bytes(seed, "00 00 00 00") 21 | for try_seed in range(0xffffffff): 22 | emu.reset_pos() 23 | print(f'seed: {hex(try_seed)}') 24 | emu.write_dword(seed, try_seed) 25 | emu.call32(ssl_key128_gen, [seed, gen]) 26 | emu.dump_n(gen, 128) 27 | #key = emu.read_bytes(gen, 128) 28 | #print(key.hex()) 29 | pos = emu.get_position() 30 | print(f'{pos} instructions emulated.') 31 | print('---') 32 | 33 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/test.py: -------------------------------------------------------------------------------- 1 | import pymwemu 2 | 3 | emu = pymwemu.init32() 4 | emu.load_maps('/home/sha0/src/mwemu/maps32/') 5 | emu.load_binary('mw/dbmm_unpacked.dll') 6 | emu.set_verbose(0) 7 | emu.set_base_address(0x1E70000) 8 | emu.enable_banzai_mode() 9 | danabot_init = 0x022EBBC0 10 | 11 | 12 | emu.disable_ctrlc() 13 | 14 | 15 | ''' 16 | public_key_ptr = emu.alloc("pubkey", 1024) 17 | private_key_ptr = emu.alloc("privkey", 1024) 18 | pub_ptr = emu.alloc("pub_ptr", 4) 19 | priv_ptr = emu.alloc("priv_ptr", 4) 20 | 21 | emu.write_dword(pub_ptr, public_key_ptr) 22 | emu.write_dword(priv_ptr, private_key_ptr) 23 | 24 | emu.enable_trace_reg(['eax']) 25 | 26 | emu.set_reg('eax', pub_ptr) 27 | emu.set_reg('edx', priv_ptr) 28 | ''' 29 | 30 | emu.set_reg('eax', 1) 31 | emu.set_reg('esi', 1) 32 | ret_addr = emu.set_reg('eip', danabot_init) 33 | emu.run(ret_addr) 34 | 35 | 36 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/vidar_strings.py: -------------------------------------------------------------------------------- 1 | import pymwemu 2 | emu = pymwemu.init32() 3 | emu.load_maps('/home/sha0/src/mwemu/maps32') 4 | emu.load_binary('mw/vidar_557_unpacked.bin') 5 | 6 | #emu.call32(0x00B01253,[]) 7 | 8 | decrypted = [] 9 | emu.set_reg('eip', 0x00B01253) 10 | while emu.step(): 11 | if emu.get_prev_mnemonic().startswith('ret'): 12 | ptr = emu.get_reg('eax') 13 | dec = emu.read_string(ptr) 14 | decrypted.append(dec) 15 | if emu.get_reg('eip') == 0x0B0408E: 16 | break 17 | 18 | 19 | 20 | print('\n'.join(decrypted)) 21 | 22 | 23 | pos = emu.get_position() 24 | print(f"emulated instructions: {pos}") 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/vidar_strings2.py: -------------------------------------------------------------------------------- 1 | import pymwemu 2 | emu = pymwemu.init32() 3 | emu.load_maps('/home/sha0/src/mwemu/maps32') 4 | emu.load_binary('mw/vidar_557_unpacked.bin') 5 | 6 | emu.call32(0x00B01253,[]) 7 | emu.show_allocs() 8 | emu.save_all_allocs("vidar/") 9 | 10 | 11 | 12 | pos = emu.get_position() 13 | print(f"emulated instructions: {pos}") 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/xloader_dexor.py: -------------------------------------------------------------------------------- 1 | import pymwemu 2 | import sys 3 | 4 | emu = pymwemu.init32() 5 | emu.load_maps('/home/sha0/src/mwemu/maps32/') 6 | emu.load_binary('mw/xl_unpacked.bin') 7 | 8 | buff = emu.alloc("struct_buff", 1024) 9 | try: 10 | emu.memset(buff, 0, 1024) # non necessary allocator fill with zeros 11 | emu.write_spaced_bytes(buff, "41 41 41 41 42 42 42 42 A1 A1 A1 A1 B2 B2 B2 B2") 12 | except: 13 | sys.exit(1) 14 | 15 | 16 | xloader_dexor = 0x3C8B97 17 | key = 0x11223344 18 | 19 | emu.set_verbose(3) 20 | #emu.spawn_console_at_pos(6) 21 | ptr = emu.call32(xloader_dexor, [buff, key]) 22 | 23 | emu.dump_n(buff, 100) 24 | 25 | 26 | -------------------------------------------------------------------------------- /pymwemu/examples/scripts/xloader_keygen.py: -------------------------------------------------------------------------------- 1 | import pymwemu 2 | import sys 3 | 4 | emu = pymwemu.init32() 5 | emu.load_maps('/home/sha0/src/mwemu/maps32/') 6 | emu.load_binary('mw/xl_unpacked.bin') 7 | 8 | buff = emu.alloc("struct_buff", 1024*2) 9 | 10 | 11 | xloader_key1_keygen = 0x3DB687 12 | key_off = 1980 13 | prekey_off = 1096 14 | 15 | emu.set_verbose(3) 16 | 17 | #emu.spawn_console_at_pos(6) 18 | eax = emu.call32(xloader_key1_keygen, [buff]) 19 | 20 | print('RC4 Key1:') 21 | emu.dump_n(buff+key_off, 20) 22 | 23 | key = emu.read_bytes(buff+key_off, 20) 24 | print(key.hex()) 25 | -------------------------------------------------------------------------------- /pymwemu/examples/xloader_keygen.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "d9ca9896-ea9b-4d66-8a83-c80247039de1", 6 | "metadata": {}, 7 | "source": [ 8 | "## Emulate xloader keygen" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "6c9e815f-860a-4a92-b60e-6d211af51a82", 15 | "metadata": { 16 | "tags": [] 17 | }, 18 | "outputs": [ 19 | { 20 | "name": "stdout", 21 | "output_type": "stream", 22 | "text": [ 23 | "RC4 KEY1: 3ce3fb3cc964415022dc8b9b042715fa2d1d2727\n" 24 | ] 25 | } 26 | ], 27 | "source": [ 28 | "import pymwemu\n", 29 | "import sys\n", 30 | "\n", 31 | "emu = pymwemu.init32()\n", 32 | "emu.load_maps('/home/sha0/src/mwemu/maps32/')\n", 33 | "emu.load_binary('/home/sha0/samples/formbook/xloader/2022-10-05/unpacked.bin')\n", 34 | "\n", 35 | "buff = emu.alloc(\"struct_buff\", 1024*2)\n", 36 | "\n", 37 | "\n", 38 | "xloader_key1_keygen = 0x3DB687\n", 39 | "key_off = 1980\n", 40 | "prekey_off = 1096\n", 41 | "\n", 42 | "emu.set_verbose(0)\n", 43 | "\n", 44 | "# emulate keygen function and all its sub-functions\n", 45 | "eax = emu.call32(xloader_key1_keygen, [buff])\n", 46 | "\n", 47 | "key1 = emu.read_bytes(buff+key_off, 20)\n", 48 | "print('RC4 KEY1: '+key1.hex())" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "id": "5d3ff859-ec82-45ec-9625-51e5508c936a", 55 | "metadata": {}, 56 | "outputs": [], 57 | "source": [] 58 | } 59 | ], 60 | "metadata": { 61 | "kernelspec": { 62 | "display_name": "Python 3", 63 | "language": "python", 64 | "name": "python3" 65 | }, 66 | "language_info": { 67 | "codemirror_mode": { 68 | "name": "ipython", 69 | "version": 3 70 | }, 71 | "file_extension": ".py", 72 | "mimetype": "text/x-python", 73 | "name": "python", 74 | "nbconvert_exporter": "python", 75 | "pygments_lexer": "ipython3", 76 | "version": "3.9.2" 77 | } 78 | }, 79 | "nbformat": 4, 80 | "nbformat_minor": 5 81 | } 82 | -------------------------------------------------------------------------------- /pymwemu/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["maturin>=0.14,<0.15"] 3 | build-backend = "maturin" 4 | 5 | [project] 6 | name = "pymwemu" 7 | version = "0.9.12" 8 | requires-python = ">=3.7" 9 | classifiers = [ 10 | "Programming Language :: Rust", 11 | "Programming Language :: Python :: Implementation :: CPython", 12 | "Programming Language :: Python :: Implementation :: PyPy", 13 | ] 14 | 15 | 16 | [tool.maturin] 17 | features = ["pyo3/extension-module"] 18 | 19 | [metadata] 20 | description = "x86 32/64bits and systems emulation" 21 | -------------------------------------------------------------------------------- /script_examples/README.md: -------------------------------------------------------------------------------- 1 | 2 | # use pymwemu from pip instead of this plugin scripting 3 | 4 | 5 | ``` 6 | ; target/release/mwemu -f ~/samples/danabot/2023-02-20/unpacked/stage2_e0000.bin -b 0xe0000 -a 0xe115c -vv -x script_examples/test.mwemu 7 | 8 | 9 | ; most of addresses and values has to be numbers like 0x123 or registers or the result varible 10 | ; except for sizes or amounts 11 | 12 | 13 | ; print the result variable 14 | pr 15 | 16 | ; print. 17 | p 18 | p this is a test 19 | 20 | ; quit. 21 | q 22 | 23 | ; show all the registers. 24 | r 25 | 26 | ; show a register, and set it value in result variable. 27 | r 28 | r rax 29 | 30 | ; register change, values always in hex. 31 | rc 32 | rc rax 0x1 33 | 34 | ; memory read, and put value in result variable. 35 | mr 36 | mr dword ptr [eax + 0x3] 37 | 38 | ; memory write. 39 | mw 40 | mw 0x123 drowd ptr [eax + 0x3] 41 | mw rsi dword ptr [eax + 0x3] 42 | 43 | ; write spaced bytes. 44 | mwb 45 | mwb 0x40000000 A1 B3 C0 FF 00 46 | mwb rax A1 B3 C0 FF 00 47 | mwb result A1 B3 C0 FF 00 48 | 49 | ; show breakpoints 50 | b 51 | 52 | ; set breakpoint on address. 53 | ba 54 | ba 0x40000000 55 | 56 | ; set breakpoint on instruction number. 57 | bi 58 | bi 33 59 | 60 | ; set breakpoint on memory read. 61 | bmr 62 | bmr 0x200000 63 | 64 | ; set breakpoint on memory write. 65 | bmw 66 | bmw 0x200000 67 | 68 | ; clear breakpoints. 69 | bc 70 | 71 | ; break on next cmp. 72 | bcmp 73 | 74 | ; clear screen. 75 | cls 76 | 77 | ; view stack. 78 | s 79 | 80 | ; set verbose. 81 | sv 82 | sv 3 83 | 84 | ; trace register. 85 | tr 86 | 87 | ; clear register trace. 88 | trc 89 | 90 | ; continue emulation. 91 | c 92 | 93 | ; continue emulation until next return. 94 | cr 95 | 96 | ; print flags. 97 | f 98 | 99 | ; clear flags. 100 | fc 101 | 102 | ; toggle zero flag. 103 | fz 104 | 105 | ; toggle sign flag. 106 | sf 107 | 108 | ; create a memory map, using the automatic allocator, the variable result get the address. 109 | mc 110 | mc mymap 1024 111 | 112 | ; create a memory map choosing the address. 113 | mca 114 | mca mymap 0x120000 1024 115 | 116 | ; load a file to a map 117 | ml 118 | ml mymap /tmp/file 119 | 120 | ; guess in chich map is located an address 121 | mn
122 | mn 0x112233 123 | 124 | ; show memory maps but only the ones allocated by the malware 125 | ma 126 | 127 | ; memory dump to see the bytes. 128 | md 129 | md 0x112233 130 | 131 | ; dump a number of dwords 132 | mrd 133 | mrd 0x112233 3 134 | 135 | ; dump a number of qwords 136 | mrq 137 | mrq 0x112233 3 138 | 139 | ; memory dump string 140 | mds 141 | mds 0x112233 142 | 143 | ; memody dump wide string 144 | mdw 145 | mdw 0x112233 146 | 147 | ; memory dump to disk 148 | mdd 149 | mdd 0x112233 1024 /tmp/blob.bin 150 | 151 | ; save all the maps allocated by the malware to a folder 152 | mdda 153 | mdda /tmp/allocs/ 154 | 155 | ; do a memory test 156 | mt 157 | 158 | ; change eip, if eip is an api will jump to it. 159 | eip 160 | eip 0x112233 161 | 162 | 163 | ; change rip, if rip is an api will jump to it. 164 | rip 165 | rip 0x1122334455 166 | 167 | 168 | ; push a value to the stack decrementing esp/rsp. 169 | push 170 | push 0x11223344 171 | 172 | ; pop value to the result variable and print it. 173 | pop 174 | 175 | ; show fpu state 176 | fpu 177 | 178 | ; perform the md5sum of a map 179 | md5 180 | md5 alloc_1 181 | 182 | ; search string 183 | ss 184 | ss mymap hello bro 185 | 186 | ; search spaced bytes 187 | sb 188 | sb mymap A1 FF 00 C3 189 | 190 | ; search spaced bytes in all the maps 191 | sba 192 | sba FF C3 1A 00 193 | 194 | ; search string in all the maps 195 | ssa 196 | ssa some string 197 | 198 | ; show the SEH 199 | seh 200 | 201 | ; show the vectorized exception pointer 202 | veh 203 | 204 | ; crawl linkedlist 205 | ll 206 | ll 0x112233 207 | 208 | ; emulate next instruction 209 | n 210 | 211 | ; print all the maps 212 | m 213 | 214 | ; primt all maps that match a keyword 215 | ms 216 | ms my 217 | 218 | ; dissasemble a block 219 | d 220 | d 0x1100 20 221 | 222 | ; show linked modules on LDR 223 | ldr 224 | 225 | ; search api details by keyword 226 | iat 227 | iat CreateFile 228 | 229 | ; search api details by exact api name 230 | iatx 231 | iatx CreateFileA 232 | 233 | ; dump module 234 | iatd 235 | 236 | ; show structre 237 | dt
238 | dt peb64 0x11020 239 | 240 | ; start conditional blocks 241 | if 242 | if rax == result 243 | if rax != 0x33 244 | if rax < 0x33 245 | 246 | ; end conditional block 247 | endif 248 | 249 | ; spawn console 250 | console 251 | 252 | ; call function, pushing parameters in reverse order 253 | call
254 | call 0x11233 0x33 0x22 rax result 255 | 256 | ; call with no arguments 257 | call
258 | call 0x112233 259 | 260 | ; set a number to the result variable 261 | set 262 | set 0x3 263 | 264 | ; loop until return is zero 265 | loop 266 | 267 | ; end loop 268 | endloop 269 | 270 | ; neable script tracing 271 | trace 272 | 273 | ``` 274 | -------------------------------------------------------------------------------- /script_examples/call.mwemu: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ; with no params 5 | call 0x112233 6 | 7 | 8 | ; three params with different types 9 | call 0x112255 0x1 rax result 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /script_examples/control_flow.mwemu: -------------------------------------------------------------------------------- 1 | ; some flow control basics 2 | 3 | ; set verbose 4 | sv 3 5 | 6 | 7 | ; next 8 | p emualte 2 steps 9 | n 10 | n 11 | 12 | ; show ip 13 | r rip 14 | 15 | if rip > 0x7f000000 16 | console 17 | endif 18 | 19 | 20 | eip 0xe115c 21 | bi 20 22 | c 23 | 24 | p instruction 20 is not emulated yet 25 | s 26 | -------------------------------------------------------------------------------- /script_examples/danabot2.mwemu: -------------------------------------------------------------------------------- 1 | 2 | ; target/release/mwemu -f ~/samples/danabot/2023-03-10-Loader/unpacked/rundll32_exe_PID974_Qruhaepdediwhf.dll_1370000_x86.dll -a 0x1ca1254 -vv -x danabot2.mwemu -vv 3 | 4 | 5 | 6 | sv 3 7 | mca danabot_stack 0x1e1f000 69633 8 | ml danabot_stack /home/sha0/samples/danabot/2023-03-10/unpacked/stack_01E1F000.bin 9 | p infection prepared 10 | bi 6106 11 | c 12 | mw 0x1e1f000 dword ptr [ebp + 0x8] 13 | bi 27571 14 | c 15 | mw 0x1 dword ptr [0x187F98D] 16 | bi 186092 17 | c 18 | mw 0x0 dword ptr [0x187F98D] 19 | console 20 | -------------------------------------------------------------------------------- /script_examples/danabot_extract.mwemu: -------------------------------------------------------------------------------- 1 | ; danabot extract 2 | 3 | sba C7 43 18 40 7E 05 00 4 | rc eip result 5 | 6 | ;d eip 100 7 | 8 | mc buff 1024 9 | rc ebx result 10 | 11 | set 0xa 12 | loop 13 | n 14 | endloop 15 | 16 | p IP Addresses: 17 | mr dword ptr [ebx + 0x6A] 18 | mr dword ptr [ebx + 0x72] 19 | mr dword ptr [ebx + 0x7A] 20 | mr dword ptr [ebx + 0x82] 21 | ;md ebx 22 | console 23 | -------------------------------------------------------------------------------- /script_examples/danabot_string.mwemu: -------------------------------------------------------------------------------- 1 | 2 | rc eax 0x0 3 | rc eip 0x01E7AF08 4 | ba 0x01E7AF1B 5 | c 6 | n 7 | console 8 | 9 | 10 | -------------------------------------------------------------------------------- /script_examples/danabot_url.mwemu: -------------------------------------------------------------------------------- 1 | ba 0x1e75c09 2 | call 0x0200F26C 0x0 3 | n 4 | n 5 | mw 0x1 dword ptr [0x2489DC4] 6 | c 7 | console 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /script_examples/loops.mwemu: -------------------------------------------------------------------------------- 1 | 2 | 3 | ; 5 emulation steps 4 | 5 | set 0x5 6 | loop 7 | pr 8 | n 9 | endloop 10 | p end. 11 | 12 | ; result: 0x5 13 | ; 1 0xe115c: push ebp ;0x22f000 14 | ; result: 0x4 15 | ; 2 0xe115d: mov ebp,esp 16 | ; result: 0x3 17 | ; 3 0xe115f: add esp,0FFFFFED0h 18 | ; result: 0x2 19 | ; 4 0xe1165: mov eax,[ebp+8] 20 | ; result: 0x1 21 | ; 5 0xe1168: mov [ebp-78h],eax 22 | ; end. 23 | 24 | 25 | ; call a function with a decremental variable 26 | set eax 27 | loop 28 | call 0x11223344 result 29 | endloop 30 | 31 | -------------------------------------------------------------------------------- /script_examples/memory.mwemu: -------------------------------------------------------------------------------- 1 | ; set verbose 2 | sv 3 3 | cls 4 | 5 | 6 | n 7 | p reading memory: 8 | mr dword ptr [ebp + 8] 9 | 10 | mw 0xe115c dword ptr [ebp + 8] 11 | p memory changed 12 | 13 | p reading memory again: 14 | mr dword ptr [ebp + 8] 15 | 16 | 17 | ; last memory or register read is in result variable 18 | 19 | if result == 0 20 | q 21 | endif 22 | 23 | 24 | ; writting bytes to memory 25 | mwb 0x112233 A1 B3 C0 FF 00 26 | mwb rax A1 B3 C0 FF 00 27 | 28 | ; viewing the bytes 29 | md 0x112233 30 | 31 | push rax 32 | push 0x11223344 33 | 34 | ; extract the 0x11223344 to result variable 35 | pop 36 | 37 | ; print result variable 38 | pr 39 | 40 | 41 | 42 | ; dump string 43 | mds 0x112233 44 | 45 | ; dump wide string 46 | mdw 0x112233 47 | 48 | ; memory dump to disk 49 | mdd 0x112233 1024 /tmp/blob.bin 50 | 51 | ; save all maps allocated by the malware to folder 52 | mdda /tmp/allocs/ 53 | 54 | 55 | ; search 56 | sb mymap A1 FF 00 C3 57 | sba A1 FF 00 C3 58 | ss data http:// 59 | ssa http:// 60 | 61 | 62 | ; crawl linked list pointed by rax 63 | ll rax 64 | 65 | 66 | 67 | p done 68 | -------------------------------------------------------------------------------- /script_examples/raccoon.mwemu: -------------------------------------------------------------------------------- 1 | ; target/release/mwemu -f ~/samples/RacoonStealer/2022-10-18/AnyDesk_dump_SCY.bin -b 0x400000 2 | 3 | 4 | ;bi 38859 5 | bi 38911 6 | call 0x040460D 7 | c 8 | ;console 9 | mdda /tmp/raccoon/ 10 | -------------------------------------------------------------------------------- /script_examples/registers.mwemu: -------------------------------------------------------------------------------- 1 | 2 | 3 | ; show regiters 4 | r 5 | r rax 6 | 7 | 8 | ; change registers 9 | rc rax 0x1 10 | rc rbx result 11 | rc rcx rax 12 | 13 | 14 | if rax == 0x1 15 | p yeah 16 | endif 17 | 18 | 19 | -------------------------------------------------------------------------------- /script_examples/test.mwemu: -------------------------------------------------------------------------------- 1 | ; set verbose 2 | sv 3 3 | 4 | p starting emulation. 5 | 6 | bi 3 7 | c 8 | 9 | p ok it stoped emulating 10 | mr dword ptr [ebp + 8] 11 | mw 0xe115c dword ptr [ebp + 8] 12 | mr dword ptr [ebp + 8] 13 | 14 | c 15 | bp 44 16 | r rax 17 | q 18 | -------------------------------------------------------------------------------- /script_examples/vidar.mwemu: -------------------------------------------------------------------------------- 1 | 2 | ;call 0x0B01253 3 | ;sv 0 4 | 5 | 6 | set 0xfff 7 | loop 8 | ba 0x0B0457F 9 | c 10 | bc 11 | ;r eax 12 | mds eax 13 | n 14 | pr 15 | endloop 16 | 17 | console 18 | -------------------------------------------------------------------------------- /scripts/build-args.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | X64DBG_TRACE_PATH = '/Users/brandon/Downloads/export-20241226-135447.csv' # x64dbg 4 | 5 | columns = "Index,Address,Bytes,Disassembly,Registers,Memory,Comments" 6 | 7 | # Read the CSV file and get the second line 8 | with open(X64DBG_TRACE_PATH, 'r') as f: 9 | # Skip the header line 10 | next(f) 11 | 12 | # Read the second line 13 | input = next(f).strip() 14 | 15 | # Split the input into fields 16 | fields = input.split(',') 17 | 18 | # Extract the entry point address and convert to int 19 | entry_address = int(fields[1].split()[0], 16) 20 | 21 | # Parse the registers string 22 | registers = fields[4] 23 | reg_dict = {} 24 | 25 | print(f"DEBUG: Raw registers string: {registers}") 26 | 27 | # Split register string into register:value pairs 28 | for reg_pair in registers.split(' r'): 29 | if not reg_pair.strip(): 30 | continue 31 | 32 | # Add 'r' back if it was removed (except for first item which might start with 'r') 33 | if not reg_pair.startswith('r'): 34 | reg_pair = 'r' + reg_pair 35 | 36 | print(f"DEBUG: Processing register pair: {reg_pair}") 37 | if ':' in reg_pair: 38 | name, value = reg_pair.split(':', 1) # Split on first colon only 39 | # Extract the first value before '->' 40 | value = value.split('->')[0].strip() 41 | print(f"DEBUG: Found register {name} = {value}") 42 | reg_dict[name] = value 43 | 44 | print(f"DEBUG: Final reg_dict: {reg_dict}") 45 | 46 | # calculate base address from entry address 47 | base_address = entry_address - 0x1035FF0 48 | 49 | # Calculate stack_address based on RSP 50 | # Convert RSP hex string to int first 51 | rsp_value = int(reg_dict['rsp'], 16) 52 | # Round down to nearest page boundary (typically 4KB/0x1000) 53 | stack_address = rsp_value & ~0xFFF # Clear the lowest 12 bits 54 | 55 | # Build the command line arguments 56 | args = [ 57 | f"--stack_address 0x{stack_address:X}", 58 | f"--base 0x{base_address:X}", 59 | f"--entry 0x{entry_address:X}", 60 | f"--rax 0x{reg_dict['rax']}", 61 | f"--rbx 0x{reg_dict['rbx']}", 62 | f"--rcx 0x{reg_dict['rcx']}", 63 | f"--rdx 0x{reg_dict['rdx']}", 64 | f"--rsp 0x{reg_dict['rsp']}", 65 | f"--rbp 0x{reg_dict['rbp']}", 66 | f"--rsi 0x{reg_dict['rsi']}", 67 | f"--rdi 0x{reg_dict['rdi']}", 68 | f"--r8 0x{reg_dict['r8']}", 69 | f"--r9 0x{reg_dict['r9']}", 70 | f"--r10 0x{reg_dict['r10']}", 71 | f"--r11 0x{reg_dict['r11']}", 72 | f"--r12 0x{reg_dict['r12']}", 73 | f"--r13 0x{reg_dict['r13']}", 74 | f"--r14 0x{reg_dict['r14']}", 75 | f"--r15 0x{reg_dict['r15']}", 76 | ] 77 | 78 | # Handle rflags separately to avoid index errors 79 | if 'rflags' in reg_dict: 80 | rflags_parts = reg_dict['rflags'].split('->') 81 | if len(rflags_parts) > 1: 82 | rflags_value = rflags_parts[1].strip() 83 | else: 84 | rflags_value = rflags_parts[0].strip() 85 | args.append(f"--rflags 0x{rflags_value}") 86 | 87 | # Print the formatted arguments 88 | print(' \\\n '.join(args)) 89 | 90 | -------------------------------------------------------------------------------- /scripts/combine-dumps.py: -------------------------------------------------------------------------------- 1 | # example: python scripts/combine-dumps.py dumps/surprise-combined-output.bin dumps/*-surprise* 2 | 3 | import os 4 | import sys 5 | from pathlib import Path 6 | 7 | def combine_binary_files(input_files, output_file): 8 | # Find the lowest and highest addresses 9 | addresses = [] 10 | print("\nProcessing files:") 11 | for filename in input_files: 12 | base_filename = filename.split('/')[-1] 13 | addr = int(base_filename.split('-')[0], 16) 14 | print(f" File: {filename}") 15 | print(f" Base filename: {base_filename}") 16 | print(f" Address: 0x{addr:x}") 17 | addresses.append(addr) 18 | 19 | base_addr = min(addresses) 20 | max_addr = max(addresses) 21 | print(f"\nAddress range:") 22 | print(f" Base address: 0x{base_addr:x}") 23 | print(f" Max address: 0x{max_addr:x}") 24 | print(f" Total size: 0x{max_addr - base_addr:x} bytes") 25 | 26 | # Create output buffer 27 | with open(output_file, 'wb') as outf: 28 | print(f"\nInitializing output file '{output_file}' with zeros") 29 | outf.seek(max_addr - base_addr) 30 | outf.write(b'\0') 31 | 32 | # Write each file at its correct offset 33 | print("\nWriting files:") 34 | for filename in input_files: 35 | base_filename = filename.split('/')[-1] 36 | addr = int(base_filename.split('-')[0], 16) 37 | offset = addr - base_addr 38 | 39 | with open(filename, 'rb') as inf: 40 | data = inf.read() 41 | end_addr = addr + len(data) 42 | print(f" Writing {base_filename}") 43 | print(f" Address Range: 0x{addr:x} - 0x{end_addr:x}") 44 | print(f" Size: 0x{len(data):x} bytes") 45 | print(f" Offset: 0x{offset:x}") 46 | outf.seek(offset) 47 | outf.write(data) 48 | 49 | print(f"\nCombined dump written to {output_file}") 50 | 51 | if __name__ == '__main__': 52 | if len(sys.argv) < 3: 53 | print("Usage: python combine_bins.py output.bin input1.bin input2.bin ...") 54 | sys.exit(1) 55 | 56 | output_file = sys.argv[1] 57 | input_files = sys.argv[2:] 58 | print("\nInitial input files:", input_files) 59 | 60 | # Filter out files ending in ldr.bin 61 | input_files = [f for f in input_files if not f.endswith('ldr.bin')] 62 | print("\nInput files (excluding ldr.bin):", input_files) 63 | 64 | # Sort input files 65 | input_files.sort(key=lambda x: int(x.split('/')[-1].split('-')[0], 16)) 66 | print("\nSorted input files:", input_files) 67 | 68 | combine_binary_files(input_files, output_file) -------------------------------------------------------------------------------- /scripts/diff-trace.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import csv 4 | 5 | MWEMU_TRACE_PATH = '/tmp/output.csv' # mwemu 6 | X64DBG_TRACE_PATH = '/Users/brandon/Desktop/pe_loader2-export-20250116-230152.csv' # x64dbg 7 | EXPECTED_HEADERS = ["Index", "Address", "Bytes", "Disassembly", "Registers", "Memory", "Comments"] 8 | EXPECTED_ENTRY = 0x000000014005D7F0 9 | 10 | def validate_headers(headers): 11 | if headers != EXPECTED_HEADERS: 12 | raise ValueError(f"Invalid CSV headers. Expected {EXPECTED_HEADERS}, got {headers}") 13 | 14 | def parse_hex(s): 15 | # Strip any leading/trailing whitespace and remove any '0x' prefix 16 | s = s.strip().replace('0x', '') 17 | # Handle empty strings 18 | if not s: 19 | return 0 20 | return int(s, 16) 21 | 22 | def calculate_offset(first_addr): 23 | """Calculate the offset needed to normalize addresses to expected RVA""" 24 | return first_addr - EXPECTED_ENTRY 25 | 26 | def compare_traces(): 27 | print(f"Opening files:") 28 | print(f"mwemu trace: {MWEMU_TRACE_PATH}") 29 | print(f"x64dbg trace: {X64DBG_TRACE_PATH}") 30 | 31 | lines_processed = 0 32 | 33 | with open(MWEMU_TRACE_PATH, 'r') as f_mwemu, open(X64DBG_TRACE_PATH, 'r') as f_x64dbg: 34 | print("Files opened successfully") 35 | 36 | mwemu_reader = csv.DictReader(f_mwemu) 37 | x64dbg_reader = csv.DictReader(f_x64dbg) 38 | 39 | # Get first row to calculate offsets 40 | mwemu_row = next(mwemu_reader) 41 | x64dbg_row = next(x64dbg_reader) 42 | 43 | # add Source column to traces 44 | mwemu_row['Source'] = 'mwemu' 45 | x64dbg_row['Source'] = 'x64dbg' 46 | 47 | # parse addresses 48 | mwemu_addr = parse_hex(mwemu_row['Address'].split()[0]) 49 | x64dbg_addr = parse_hex(x64dbg_row['Address'].split()[0]) 50 | 51 | # Calculate offsets based on first address 52 | mwemu_offset = calculate_offset(mwemu_addr) 53 | x64dbg_offset = calculate_offset(x64dbg_addr) 54 | 55 | # check if x64dbg row is out of range 56 | entry_rva = 0x005D7F0 57 | x64dbg_base = x64dbg_addr - entry_rva 58 | text_start = 0x1000 59 | text_end = 0x60000 60 | 61 | if x64dbg_addr < x64dbg_base + text_start or x64dbg_addr > x64dbg_base + text_end: 62 | print(f"x64dbg row is out of range: 0x{x64dbg_addr:x}") 63 | return 64 | 65 | print(f"x64dbg base: 0x{x64dbg_base:x}") 66 | print(f"text start: 0x{text_start:x}") 67 | print(f"text end: 0x{text_end:x}") 68 | 69 | print(f"mwemu trace offset: 0x{mwemu_offset:x}") 70 | print(f"x64dbg trace offset: 0x{x64dbg_offset:x}") 71 | 72 | # Add buffer for previous lines 73 | mwemu_prev_lines = [(parse_hex(mwemu_row['Index']), 74 | parse_hex(mwemu_row['Address'].split()[0]) - mwemu_offset, 75 | mwemu_row)] 76 | x64dbg_prev_lines = [(parse_hex(x64dbg_row['Index']), 77 | parse_hex(x64dbg_row['Address'].split()[0]) - x64dbg_offset, 78 | x64dbg_row)] 79 | max_history = 10 80 | 81 | # Compare all rows 82 | for row_num, (mwemu_row, x64dbg_row) in enumerate(zip(mwemu_reader, x64dbg_reader), start=2): 83 | mwemu_idx = parse_hex(mwemu_row['Index']) 84 | x64dbg_idx = parse_hex(x64dbg_row['Index']) 85 | mwemu_addr = parse_hex(mwemu_row['Address'].split()[0]) - mwemu_offset 86 | x64dbg_addr = parse_hex(x64dbg_row['Address'].split()[0]) - x64dbg_offset 87 | 88 | # add Source column to traces 89 | mwemu_row['Source'] = 'mwemu' 90 | x64dbg_row['Source'] = 'x64dbg' 91 | 92 | # Store current line in history 93 | mwemu_prev_lines.append((mwemu_idx, mwemu_addr, mwemu_row)) 94 | x64dbg_prev_lines.append((x64dbg_idx, x64dbg_addr, x64dbg_row)) 95 | if len(mwemu_prev_lines) > max_history: 96 | mwemu_prev_lines.pop(0) 97 | x64dbg_prev_lines.pop(0) 98 | 99 | if mwemu_idx != x64dbg_idx or mwemu_addr != x64dbg_addr: 100 | print(f"\nDifference found at row {row_num}:") 101 | 102 | print(f"mwemu_idx: {mwemu_idx:x}") 103 | print(f"x64dbg_idx: {x64dbg_idx:x}") 104 | print(f"mwemu_addr: {mwemu_addr:x}") 105 | print(f"x64dbg_addr: {x64dbg_addr + x64dbg_offset:x}") 106 | 107 | print(f"\nPrevious {max_history} lines from mwemu trace:") 108 | for prev_idx, prev_addr, prev_row in mwemu_prev_lines: 109 | print(f"{prev_row}") 110 | print(f"\nPrevious {max_history} lines from x64dbg trace:") 111 | for prev_idx, prev_addr, prev_row in x64dbg_prev_lines: 112 | print(f"{prev_row}") 113 | return 114 | 115 | lines_processed += 1 116 | if lines_processed % 100000 == 0: 117 | print(f"Processed {lines_processed} lines") 118 | 119 | if __name__ == '__main__': 120 | try: 121 | compare_traces() 122 | except Exception as e: 123 | print(f"Error: {e}") 124 | -------------------------------------------------------------------------------- /scripts/enigma-protector.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | 5 | export RUST_BACKTRACE=1 6 | export RUST_LOG=debug 7 | 8 | # Check if mode parameter is provided 9 | if [ -z "$1" ]; then 10 | echo "Error: Mode parameter required (dump/load)" 11 | exit 1 12 | fi 13 | 14 | MODE=$1 15 | 16 | # Set target architecture based on OS 17 | if [[ "$OSTYPE" == "msys"* ]] || [[ "$OSTYPE" == "cygwin"* ]]; then 18 | TARGET=x86_64-pc-windows-msvc 19 | else 20 | TARGET=aarch64-apple-darwin 21 | fi 22 | 23 | # Execute based on mode 24 | if [ "$MODE" == "dump" ]; then 25 | cargo run \ 26 | -p mwemu \ 27 | --release \ 28 | --target $TARGET \ 29 | -- \ 30 | --filename ~/Desktop/enigma/pe_loader-20250122-v2.exe \ 31 | --maps ./maps64/ \ 32 | --64bits \ 33 | -vv 34 | elif [ "$MODE" == "dump_verbose" ]; then 35 | cargo run \ 36 | -p mwemu \ 37 | --release \ 38 | --target $TARGET \ 39 | -- \ 40 | --filename ~/Desktop/enigma/surprise.dll \ 41 | --trace /tmp/output.csv \ 42 | --maps ./maps64/ \ 43 | --64bits \ 44 | --rcx 0x180000000 \ 45 | --rdx 1 \ 46 | --r8 0 \ 47 | -vvv \ 48 | --memory \ 49 | --regs \ 50 | --exit 1000000 51 | elif [ "$MODE" == "load" ]; then 52 | cargo run \ 53 | -p mwemu \ 54 | --release \ 55 | --target $TARGET \ 56 | -- \ 57 | --filename ~/Desktop/enigma/surprise.dll \ 58 | --maps ./maps64/ \ 59 | --64bits \ 60 | --rcx 0x180000000 \ 61 | --rdx 1 \ 62 | --r8 0 \ 63 | --dump ./dumps/emu-232321175.bin 64 | elif [ "$MODE" == "load_verbose" ]; then 65 | cargo run \ 66 | -p mwemu \ 67 | --release \ 68 | --target $TARGET \ 69 | -- \ 70 | --filename ~/Desktop/enigma/surprise.dll \ 71 | --maps ./maps64/ \ 72 | --64bits \ 73 | --dump ./dumps/emu-232321175.bin \ 74 | -vvv \ 75 | --memory \ 76 | --regs \ 77 | -p \ 78 | --banzai \ 79 | --rcx 0x180000000 \ 80 | --rdx 1 \ 81 | --r8 0 \ 82 | --trace /tmp/output.csv 83 | else 84 | echo "Error: Invalid mode. Use 'dump' or 'load'" 85 | exit 1 86 | fi 87 | -------------------------------------------------------------------------------- /scripts/enigma-protector2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | 5 | export RUST_BACKTRACE=1 6 | export RUST_LOG=debug 7 | 8 | # Check if mode parameter is provided 9 | if [ -z "$1" ]; then 10 | echo "Error: Mode parameter required (dump/load)" 11 | exit 1 12 | fi 13 | 14 | MODE=$1 15 | 16 | 17 | # Execute based on mode 18 | if [ "$MODE" == "dump" ]; then 19 | cargo run \ 20 | -p mwemu \ 21 | --release \ 22 | -- \ 23 | --filename ~/Descargas/Telegram\ Desktop/pe_loader-972d88c51f4cb4ba_0000000180000000.bin \ 24 | --maps ./maps64/ \ 25 | --64bits \ 26 | --rcx 0x110000000 \ 27 | --rdx 1 \ 28 | --r8 0 -vv 29 | #-c 278006 30 | #-C 180055e7e 31 | #-C 0x180055e84 32 | mv ./dumps/emu.bin ./dumps/emu-232321175.bin 33 | elif [ "$MODE" == "dump_verbose" ]; then 34 | cargo run \ 35 | -p mwemu \ 36 | --release \ 37 | --target $TARGET \ 38 | -- \ 39 | --filename ~/Downloads/enigma/surprise.dll \ 40 | --maps ./maps64/ \ 41 | --64bits \ 42 | --rdx 1 \ 43 | -vvv \ 44 | --memory \ 45 | --regs \ 46 | -p \ 47 | --banzai \ 48 | --rcx 0x180000000 \ 49 | --rdx 1 \ 50 | --r8 0 \ 51 | --trace /tmp/output.csv 52 | elif [ "$MODE" == "load" ]; then 53 | cargo run \ 54 | -p mwemu \ 55 | --release \ 56 | --target $TARGET \ 57 | -- \ 58 | --filename ~/Downloads/enigma/surprise.dll \ 59 | --maps ./maps64/ \ 60 | --64bits \ 61 | --dump ./dumps/emu-232321175.bin \ 62 | -vvv \ 63 | --memory \ 64 | --regs \ 65 | -p \ 66 | --banzai \ 67 | --rcx 0x180000000 \ 68 | --rdx 1 \ 69 | --r8 0 \ 70 | --trace /tmp/output.csv 71 | else 72 | echo "Error: Invalid mode. Use 'dump' or 'load'" 73 | exit 1 74 | fi 75 | -------------------------------------------------------------------------------- /scripts/ghidra_mwemu.py: -------------------------------------------------------------------------------- 1 | ''' 2 | View in ghidra the trace of emulation by changin color of emulated instructions, and save a call log with ghidra function names. 3 | 4 | 1. store mwemu trace with verbose 5 | cargo run --release -- -6 -vv -f file.bin > log 2>&1 6 | 7 | 2. put this script here and launch it from hidra with the same binary opened. 8 | /Users/jesus/ghidra/Ghidra/Features/Jython/ghidra_scripts 9 | ''' 10 | 11 | 12 | import os 13 | import re 14 | from java.awt import Color 15 | from ghidra.program.model.address import Address 16 | from ghidra.program.model.address import AddressSet 17 | 18 | def parse_emulation_log(file_path): 19 | EMULATION_MARKER = " ----- emulation -----" 20 | ADDRESS_PATTERN = r"^([0-9]+)\s+(0x[0-9a-fA-F]+)" 21 | CALL_PATTERN = r"call\s+([0-9a-fA-F]+)h" 22 | 23 | address_regex = re.compile(ADDRESS_PATTERN) 24 | call_regex = re.compile(CALL_PATTERN) 25 | 26 | addresses = [] 27 | call_output_path = os.path.splitext(file_path)[0] + ".call" 28 | 29 | with open(call_output_path, "w") as call_file: 30 | with open(file_path, "r") as log_file: 31 | lines = log_file.readlines() 32 | marker_found = False 33 | for line in lines: 34 | if EMULATION_MARKER in line: 35 | marker_found = True 36 | continue 37 | 38 | if marker_found: 39 | address_match = address_regex.search(line) 40 | if address_match: 41 | address = address_match.group(2) 42 | addresses.append(address) 43 | 44 | call_match = call_regex.search(line) 45 | if call_match: 46 | call_address_hex = call_match.group(1) 47 | call_address_str = "0x" + call_address_hex 48 | function_name = get_function_name(call_address_str) 49 | if function_name: 50 | call_file.write("Call to function: {} at address {}\n".format(function_name, call_address_str)) 51 | else: 52 | call_file.write("No function name found for address: {}\n".format(call_address_str)) 53 | 54 | print("Call data saved to {}".format(call_output_path)) 55 | return addresses 56 | 57 | def get_function_name(address_str): 58 | current_program = getCurrentProgram() 59 | symbol_table = current_program.getSymbolTable() 60 | address = toAddr(address_str) 61 | symbol = symbol_table.getPrimarySymbol(address) 62 | 63 | if symbol: 64 | return symbol.getName() 65 | 66 | function_manager = current_program.getFunctionManager() 67 | function = function_manager.getFunctionAt(address) 68 | if function: 69 | return function.getName() 70 | 71 | return None 72 | 73 | def highlight_addresses(addresses): 74 | current_program = getCurrentProgram() 75 | listing = current_program.getListing() 76 | 77 | min_address = current_program.getMinAddress() 78 | max_address = current_program.getMaxAddress() 79 | 80 | address_set = AddressSet() 81 | valid_addresses = 0 82 | 83 | for address_str in addresses: 84 | address = toAddr(address_str) 85 | if min_address <= address <= max_address: 86 | address_set.add(address) 87 | valid_addresses += 1 88 | 89 | setBackgroundColor(address_set, Color(169, 169, 169)) 90 | print("{} addresses were highlighted!".format(valid_addresses)) 91 | 92 | log_file_path = askFile("Select Emulation Log File", "Open").getAbsolutePath() 93 | 94 | instruction_addresses = parse_emulation_log(log_file_path) 95 | 96 | highlight_addresses(instruction_addresses) 97 | 98 | print("Script completed successfully!") 99 | -------------------------------------------------------------------------------- /scripts/trace-converter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import struct 3 | import sys 4 | 5 | def read_uint64_from_binary(filename): 6 | index = 0 7 | 8 | try: 9 | with open(filename, 'rb') as file: 10 | while True: 11 | # Read 8 bytes at a time 12 | bytes_read = file.read(8) 13 | 14 | # Break if we've reached the end of file or don't have enough bytes 15 | if not bytes_read or len(bytes_read) < 8: 16 | break 17 | 18 | # Unpack as uint64 (little-endian) and convert to hex 19 | value = struct.unpack('") 38 | sys.exit(1) 39 | 40 | print("Index,Address,Bytes,Disassembly,Registers,Memory,Comments") 41 | read_uint64_from_binary(sys.argv[1]) --------------------------------------------------------------------------------