|
| 1 | +# Reversing Tools & Basic Methods |
| 2 | + |
| 3 | +## Wasm decompiler / Wat compiler |
| 4 | + |
| 5 | +Online: |
| 6 | + |
| 7 | +* Use [https://webassembly.github.io/wabt/demo/wasm2wat/index.html](https://webassembly.github.io/wabt/demo/wasm2wat/index.html) to **decompile** from wasm \(binary\) to wat \(clear text\) |
| 8 | +* Use [https://webassembly.github.io/wabt/demo/wat2wasm/](https://webassembly.github.io/wabt/demo/wat2wasm/) to **compile** from wat to wasm |
| 9 | +* you can also try to use [https://wwwg.github.io/web-wasmdec/](https://wwwg.github.io/web-wasmdec/) to decompile |
| 10 | + |
| 11 | +Software: |
| 12 | + |
| 13 | +* [https://www.pnfsoftware.com/jeb/demo](https://www.pnfsoftware.com/jeb/demo) |
| 14 | +* [https://github.com/wwwg/wasmdec](https://github.com/wwwg/wasmdec) |
| 15 | + |
| 16 | +## .Net decompiler |
| 17 | + |
| 18 | +[https://github.com/icsharpcode/ILSpy](https://github.com/icsharpcode/ILSpy) |
| 19 | +[ILSpy plugin for Visual Studio Code](https://github.com/icsharpcode/ilspy-vscode): You can have it in any OS \(you can install it directly from VSCode, no need to download the git. Click on **Extensions** and **search ILSpy**\). |
| 20 | +If you need to **decompile**, **modify** and **recompile** again you can use: [**https://github.com/0xd4d/dnSpy/releases**](https://github.com/0xd4d/dnSpy/releases) \(**Right Click -> Modify Method** to change something inside a function\). |
| 21 | +You cloud also try [https://www.jetbrains.com/es-es/decompiler/](https://www.jetbrains.com/es-es/decompiler/) |
| 22 | + |
| 23 | +### DNSpy Logging |
| 24 | + |
| 25 | +In order to make **DNSpy log some information in a file**, you could use this .Net lines: |
| 26 | + |
| 27 | +```bash |
| 28 | +using System.IO; |
| 29 | +path = "C:\\inetpub\\temp\\MyTest2.txt"; |
| 30 | +File.AppendAllText(path, "Password: " + password + "\n"); |
| 31 | +``` |
| 32 | + |
| 33 | +### DNSpy Debugging |
| 34 | + |
| 35 | +In order to debug code using DNSpy you need to: |
| 36 | + |
| 37 | +First, change the **Assembly attributes** related to **debugging**: |
| 38 | + |
| 39 | + |
| 40 | + |
| 41 | +From: |
| 42 | + |
| 43 | +```aspnet |
| 44 | +[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] |
| 45 | +``` |
| 46 | + |
| 47 | +To: |
| 48 | + |
| 49 | +```text |
| 50 | +[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | |
| 51 | +DebuggableAttribute.DebuggingModes.DisableOptimizations | |
| 52 | +DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | |
| 53 | +DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] |
| 54 | +``` |
| 55 | + |
| 56 | +And click on **compile**: |
| 57 | + |
| 58 | + |
| 59 | + |
| 60 | +Then save the new file on _**File >> Save module...**_: |
| 61 | + |
| 62 | + |
| 63 | + |
| 64 | +This is necessary because if you don't do this, at **runtime** several **optimisations** will be applied to the code and it could be possible that while debugging a **break-point is never hit** or some **variables don't exist**. |
| 65 | + |
| 66 | +Then, if your .Net application is being **run** by **IIS** you can **restart** it with: |
| 67 | + |
| 68 | +```text |
| 69 | +iisreset /noforce |
| 70 | +``` |
| 71 | + |
| 72 | +Then, in order to start debugging you should close all the opened files and inside the **Debug Tab** select **Attach to Process...**: |
| 73 | + |
| 74 | + |
| 75 | + |
| 76 | +Then select **w3wp.exe** to attach to the **IIS server** and click **attach**: |
| 77 | + |
| 78 | + |
| 79 | + |
| 80 | +Now that we are debugging the process, it's time to stop it and load all the modules. First click on _Debug >> Break All_ and then click on _**Debug >> Windows >> Modules**_: |
| 81 | + |
| 82 | + |
| 83 | + |
| 84 | + |
| 85 | + |
| 86 | +Click any module on **Modules** and selec**t Open All Modules**: |
| 87 | + |
| 88 | + |
| 89 | + |
| 90 | +Right click any module in **Assembly Explorer** and click **Sort Assemblies**: |
| 91 | + |
| 92 | + |
| 93 | + |
| 94 | +## Java decompiler |
| 95 | + |
| 96 | +[https://github.com/skylot/jadx](https://github.com/skylot/jadx) |
| 97 | +[https://github.com/java-decompiler/jd-gui/releases](https://github.com/java-decompiler/jd-gui/releases) |
| 98 | + |
| 99 | +## Debugging DLLs |
| 100 | + |
| 101 | +### Using IDA |
| 102 | + |
| 103 | +* **Load rundll32** \(64bits in C:\Windows\System32\rundll32.exe and 32 bits in C:\Windows\SysWOW64\rundll32.exe\) |
| 104 | +* Select **Windbg** debugger |
| 105 | +* Select "**Suspend on library load/unload**" |
| 106 | + |
| 107 | + |
| 108 | + |
| 109 | +* Configure the **parameters** of the execution putting the **path to the DLL** and the function that you want to call: |
| 110 | + |
| 111 | + |
| 112 | + |
| 113 | +Then, when you start debugging **the execution will be stopped when each DLL is loaded**, then, when rundll32 load your DLL the execution will be stopped. |
| 114 | + |
| 115 | +But, how can you get to the code of the DLL that was lodaded? Using this method, I don't know how. |
| 116 | + |
| 117 | +### Using x64dbg/x32dbg |
| 118 | + |
| 119 | +* **Load rundll32** \(64bits in C:\Windows\System32\rundll32.exe and 32 bits in C:\Windows\SysWOW64\rundll32.exe\) |
| 120 | +* **Change the Command Line** \( _File --> Change Command Line_ \) and set the path of the dll and the function that you want to call, for example: "C:\Windows\SysWOW64\rundll32.exe" "Z:\shared\Cybercamp\rev2\\14.ridii\_2.dll",DLLMain |
| 121 | +* Change _Options --> Settings_ and select "**DLL Entry**". |
| 122 | +* Then **start the execution**, the debugger will stop at each dll main, at some point you will **stop in the dll Entry of your dll**. From there, just search for the points where you want to put a breakpoint. |
| 123 | + |
| 124 | +Notice that when the execution is stopped by any reason in win64dbg you can see **in which code you are** looking in the **top of the win64dbg window**: |
| 125 | + |
| 126 | + |
| 127 | + |
| 128 | +Then, looking to this ca see when the execution was stopped in the dll you want to debug. |
| 129 | + |
| 130 | +## ARM & MIPS |
| 131 | + |
| 132 | +{% embed url="https://github.com/nongiach/arm\_now" %} |
| 133 | + |
| 134 | +## Shellcodes |
| 135 | + |
| 136 | +### Debugging a shellcode with blobrunner |
| 137 | + |
| 138 | +[**Blobrunner**](https://github.com/OALabs/BlobRunner) will **allocate** the **shellcode** inside a space of memory, will **indicate** you the **memory address** were the shellcode was allocated and will **stop** the execution. |
| 139 | +Then, you need to **attach a debugger** \(Ida or x64dbg\) to the process and put a **breakpoint the indicated memory address** and **resume** the execution. This way you will be debugging the shellcode. |
| 140 | + |
| 141 | +The releases github page contains zips containing the compiled releases: [https://github.com/OALabs/BlobRunner/releases/tag/v0.0.5](https://github.com/OALabs/BlobRunner/releases/tag/v0.0.5) |
| 142 | +You can find a slightly modified version of Blobrunner in the following link. In order to compile it just **create a C/C++ project in Visual Studio Code, copy and paste the code and build it**. |
| 143 | + |
| 144 | +{% page-ref page="blobrunner.md" %} |
| 145 | + |
| 146 | +### Debugging a shellcode with jmp2it |
| 147 | + |
| 148 | +\*\*\*\*[**jmp2it** ](https://github.com/adamkramer/jmp2it/releases/tag/v1.4)is very similar to blobrunner. It will **allocate** the **shellcode** inside a space of memory, and start an **eternal loop**. You then need to **attach the debugger** to the process, **play start wait 2-5 secs and press stop** and you will find yourself inside the **eternal loop**. Jump to the next instruction of the eternal loop as it will be a call to the shellcode, and finally you will find yourself executing the shellcode. |
| 149 | + |
| 150 | + |
| 151 | + |
| 152 | +You can download a compiled version of [jmp2it inside the releases page](https://github.com/adamkramer/jmp2it/releases/). |
| 153 | + |
| 154 | +### Debugging shellcode using Cutter |
| 155 | + |
| 156 | +\*\*\*\*[**Cutter**](https://github.com/rizinorg/cutter/releases/tag/v1.12.0) is the GUI of radare. Using cutter you can emulate the shellcode and inspect it dynamically. |
| 157 | + |
| 158 | +Note that Cutter allows you to "Open File" and "Open Shellcode". In my case when I opened the shellcode as a file it decompiled it correctly, but when I opened it as a shellcode it didn't: |
| 159 | + |
| 160 | + |
| 161 | + |
| 162 | +In order to start the emulation in the place you want to, set a bp there and apparently cutter will automatically start the emulation from there: |
| 163 | + |
| 164 | + |
| 165 | + |
| 166 | + |
| 167 | + |
| 168 | +You can see the stack for example inside a hex dump: |
| 169 | + |
| 170 | + |
| 171 | + |
| 172 | +### Deobfuscating shellcode and getting executed functions |
| 173 | + |
| 174 | +You should try ****[**scdbg**](http://sandsprite.com/blogs/index.php?uid=7&pid=152). |
| 175 | +It will tell you things like **which functions** is the shellcode using and if the shellcode is **decoding** itself in memory. |
| 176 | + |
| 177 | +```bash |
| 178 | +scdbg.exe -f shellcode # Get info |
| 179 | +scdbg.exe -f shellcode -r #show analysis report at end of run |
| 180 | +scdbg.exe -f shellcode -i -r #enable interactive hooks (file and network) and show analysis report at end of run |
| 181 | +scdbg.exe -f shellcode -d #Dump decoded shellcode |
| 182 | +scdbg.exe -f shellcode /findsc #Find offset where starts |
| 183 | +scdbg.exe -f shellcode /foff 0x0000004D #Start the executing in that offset |
| 184 | +``` |
| 185 | + |
| 186 | +scDbg also counts with a graphical launcher where you can select the options you want and execute the shellcode |
| 187 | + |
| 188 | + |
| 189 | + |
| 190 | +The **Create Dump** option will dump the final shellcode if any change is done to the shellcode dynamically in memory \(useful to download the decoded shellcode\). The **start offset** can be useful to start the shellcode at a specific offset. The **Debug Shell** option is useful to debug the shellcode using the scDbg terminal \(however I find any of the options explained before better for this matter as you will be able to use Ida or x64dbg\). |
| 191 | + |
| 192 | +### Disassembling using CyberChef |
| 193 | + |
| 194 | +Upload you shellcode file as input and use the following receipt to decompile it: [https://gchq.github.io/CyberChef/\#recipe=To\_Hex\('Space',0\)Disassemble\_x86\('32','Full%20x86%20architecture',16,0,true,true\)](https://gchq.github.io/CyberChef/#recipe=To_Hex%28'Space',0%29Disassemble_x86%28'32','Full%20x86%20architecture',16,0,true,true%29) |
| 195 | + |
| 196 | +## [Movfuscator](https://github.com/xoreaxeaxeax/movfuscator) |
| 197 | + |
| 198 | +This obfuscator **modify all the instructions for `mov`**\(yeah, really cool\). It also uses interruptions to change executions flows. For more information about how does it works: |
| 199 | + |
| 200 | +* [https://www.youtube.com/watch?v=2VF\_wPkiBJY](https://www.youtube.com/watch?v=2VF_wPkiBJY) |
| 201 | +* [https://github.com/xoreaxeaxeax/movfuscator/blob/master/slides/domas\_2015\_the\_movfuscator.pdf](https://github.com/xoreaxeaxeax/movfuscator/blob/master/slides/domas_2015_the_movfuscator.pdf) |
| 202 | + |
| 203 | +If you are lucky [demovfuscator ](https://github.com/kirschju/demovfuscator)will deofuscate the binary. It has several dependencies |
| 204 | + |
| 205 | +```text |
| 206 | +apt-get install libcapstone-dev |
| 207 | +apt-get install libz3-dev |
| 208 | +``` |
| 209 | + |
| 210 | +And [install keystone](https://github.com/keystone-engine/keystone/blob/master/docs/COMPILE-NIX.md) \(`apt-get install cmake; mkdir build; cd build; ../make-share.sh; make install`\) |
| 211 | + |
| 212 | +If you are playing a **CTF, this workaround to find the flag** could be very useful: [https://dustri.org/b/defeating-the-recons-movfuscator-crackme.html](https://dustri.org/b/defeating-the-recons-movfuscator-crackme.html) |
| 213 | + |
| 214 | +## Delphi |
| 215 | + |
| 216 | +For Delphi compiled binaries you can use [https://github.com/crypto2011/IDR](https://github.com/crypto2011/IDR) |
| 217 | + |
| 218 | +## GBA - Game Body Advance |
| 219 | + |
| 220 | +If you get the **binary** of a GBA game you can use different tools to **emulate** and **debug** it: |
| 221 | + |
| 222 | +* \*\*\*\*[**no$gba**](https://problemkaputt.de/gba.htm) \(_Download the debug version_\) - Contains a debugger with interface |
| 223 | +* \*\*\*\*[**mgba** ](https://mgba.io/)- Contains a CLI debugger |
| 224 | +* \*\*\*\*[**gba-ghidra-loader**](https://github.com/pudii/gba-ghidra-loader) ****- Ghidra plugin |
| 225 | +* [**GhidraGBA**](https://github.com/SiD3W4y/GhidraGBA) ****- Ghidra plugin |
| 226 | + |
| 227 | +In [**no$gba**](https://problemkaputt.de/gba.htm), in _**Options --> Emulation Setup --> Controls**_ ****you can see how to press the Game Boy Advance **buttons** |
| 228 | + |
| 229 | + |
| 230 | + |
| 231 | +When pressed, each **key has a value** to identify it: |
| 232 | + |
| 233 | +```text |
| 234 | +A = 1 |
| 235 | +B = 2 |
| 236 | +SELECT = 4 |
| 237 | +START = 8 |
| 238 | +RIGHT = 16 |
| 239 | +LEFT = 32 |
| 240 | +UP = 64 |
| 241 | +DOWN = 128 |
| 242 | +R = 256 |
| 243 | +L = 256 |
| 244 | +``` |
| 245 | + |
| 246 | +So, in this kind of programs, the an interesting part will be **how the program treats the user input**. In the address **0x4000130** you will find the commonly found function: **KEYINPUT.** |
| 247 | + |
| 248 | + |
| 249 | + |
| 250 | +In the previous image you can find that the function is called from **FUN\_080015a8** \(addresses: _0x080015fa_ and _0x080017ac_\). |
| 251 | + |
| 252 | +In that function, after some init operations \(without any importance\): |
| 253 | + |
| 254 | +```c |
| 255 | +void FUN_080015a8(void) |
| 256 | + |
| 257 | +{ |
| 258 | + ushort uVar1; |
| 259 | + undefined4 uVar2; |
| 260 | + undefined4 uVar3; |
| 261 | + ushort uVar4; |
| 262 | + int iVar5; |
| 263 | + ushort *puVar6; |
| 264 | + undefined *local_2c; |
| 265 | + |
| 266 | + DISPCNT = 0x1140; |
| 267 | + FUN_08000a74(); |
| 268 | + FUN_08000ce4(1); |
| 269 | + DISPCNT = 0x404; |
| 270 | + FUN_08000dd0(&DAT_02009584,0x6000000,&DAT_030000dc); |
| 271 | + FUN_08000354(&DAT_030000dc,0x3c); |
| 272 | + uVar4 = DAT_030004d8; |
| 273 | +``` |
| 274 | +
|
| 275 | + It's found this code: |
| 276 | +
|
| 277 | +```c |
| 278 | + do { |
| 279 | + DAT_030004da = uVar4; //This is the last key pressed |
| 280 | + DAT_030004d8 = KEYINPUT | 0xfc00; |
| 281 | + puVar6 = &DAT_0200b03c; |
| 282 | + uVar4 = DAT_030004d8; |
| 283 | + do { |
| 284 | + uVar2 = DAT_030004dc; |
| 285 | + uVar1 = *puVar6; |
| 286 | + if ((uVar1 & DAT_030004da & ~uVar4) != 0) { |
| 287 | +``` |
| 288 | + |
| 289 | +The last if is checking **`uVar4`** is in the **last Keys** and not is the current key, also called letting go off a button \(current key is stored in **`uVar1`**\). |
| 290 | + |
| 291 | +```c |
| 292 | + if (uVar1 == 4) { |
| 293 | + DAT_030000d4 = 0; |
| 294 | + uVar3 = FUN_08001c24(DAT_030004dc); |
| 295 | + FUN_08001868(uVar2,0,uVar3); |
| 296 | + DAT_05000000 = 0x1483; |
| 297 | + FUN_08001844(&DAT_0200ba18); |
| 298 | + FUN_08001844(&DAT_0200ba20,&DAT_0200ba40); |
| 299 | + DAT_030000d8 = 0; |
| 300 | + uVar4 = DAT_030004d8; |
| 301 | + } |
| 302 | + else { |
| 303 | + if (uVar1 == 8) { |
| 304 | + if (DAT_030000d8 == 0xf3) { |
| 305 | + DISPCNT = 0x404; |
| 306 | + FUN_08000dd0(&DAT_02008aac,0x6000000,&DAT_030000dc); |
| 307 | + FUN_08000354(&DAT_030000dc,0x3c); |
| 308 | + uVar4 = DAT_030004d8; |
| 309 | + } |
| 310 | + } |
| 311 | + else { |
| 312 | + if (DAT_030000d4 < 8) { |
| 313 | + DAT_030000d4 = DAT_030000d4 + 1; |
| 314 | + FUN_08000864(); |
| 315 | + if (uVar1 == 0x10) { |
| 316 | + DAT_030000d8 = DAT_030000d8 + 0x3a; |
| 317 | +``` |
| 318 | +
|
| 319 | +In the previous code you can see that we are comparing **uVar1** \(the place where the **value of the pressed button** is\) with some values: |
| 320 | +
|
| 321 | +* First, it's compared with the **value 4** \(**SELECT** button\): In the challenge this button clears the screen |
| 322 | +* Then, it's comparing it with the **value 8** \(**START** button\): In the challenge this checks is the code is valid to get the flag. |
| 323 | + * In this case the var **`DAT_030000d8`** is compared with 0xf3 and if the value is the same some code is executed. |
| 324 | +* In any other cases, some cont \(`DAT_030000d4`\) is checked. It's a cont because it's adding 1 right after entering in the code. **I**f less than 8 something that involves **adding** values to **`DAT_030000d8`** is done \(basically it's adding the values of the keys pressed in this variable as long as the cont is less than 8\). |
| 325 | +
|
| 326 | +So, in this challenge, knowing the values of the buttons, you needed to **press a combination with a length smaller than 8 that the resulting addition is 0xf3.** |
| 327 | +
|
| 328 | +**Reference for this tutorial:** [**https://exp.codes/Nostalgia/**](https://exp.codes/Nostalgia/)\*\*\*\* |
| 329 | +
|
| 330 | +## Game Boy |
| 331 | +
|
| 332 | +{% embed url="https://www.youtube.com/watch?v=VVbRe7wr3G4" %} |
| 333 | +
|
| 334 | +## Courses |
| 335 | +
|
| 336 | +* [https://github.com/0xZ0F/Z0FCourse\_ReverseEngineering](https://github.com/0xZ0F/Z0FCourse_ReverseEngineering) |
| 337 | +* [https://github.com/malrev/ABD](https://github.com/malrev/ABD) \(Binary deobfuscation\) |
| 338 | +
|
0 commit comments