- Dissecting Go Binaries
- Go: Overview of the Compiler
- Go compiler internals: adding a new statement to Go - Part 1
- Go compiler internals: adding a new statement to Go - Part 2
- Reversing GO binaries like a pro
- How a Go Program Compiles down to Machine Code
- Analyzing Golang Executables
- Go Reverse Engineering Tool Kit
- go-internals book
- [Reconstructing Program Semantics from Go Binaries](http://home.in.tum.de/
| from idaapi import PluginForm | |
| from PyQt5 import QtCore, QtGui, QtWidgets | |
| import sip | |
| class MyPluginFormClass(PluginForm): | |
| def OnCreate(self, form): | |
| """ | |
| Called when the widget is created | |
| """ |
| # IDAPYTHON 7.4 | |
| id = idc.add_enum(-1, "PROCESSINFOCLASS", idaapi.hex_flag()) | |
| # 0x0 ProcessBasicInformation, // 0, q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION | |
| idc.add_enum_member(id, "ProcessBasicInformation", 0, -1) | |
| # 0x1 ProcessQuotaLimits, // 1, qs: QUOTA_LIMITS, QUOTA_LIMITS_EX | |
| idc.add_enum_member(id, "ProcessQuotaLimits", 1, -1) | |
| # 0x2 ProcessIoCounters, // 2, q: IO_COUNTERS | |
| idc.add_enum_member(id, "ProcessIoCounters", 2, -1) | |
| # 0x3 ProcessVmCounters, //3, q: VM_COUNTERS, VM_COUNTERS_EX, VM_COUNTERS_EX2 | |
| idc.add_enum_member(id, "ProcessVmCounters", 3, -1) |
Recent variants of Ryuk have had their code cleaned up. They removed non-referenced strings that are relics from the HERMES source code days. One interesting part of the code clean-up is a new string decoder. The string decoder is the first MD5 brute forcer that I have observed in malware. It's an interesting technique because it is a computational attack that delays execution of Ryuk before the strings are decoded in memory. The decoding of strings happens in two phases. The first phase uses a hardcoded lookup table that is to decode API names. Once the API names are decrypted, they are dynamically imported and then used to recover the original string from an MD5 hash. After the original string is discovered, each byte of the string is hashed and then the hash is MD5ed, then the hexdigest contents are appended to a string. Each byte within the appended MD5 strings is used to create a second lookup table which is then used to decrypt strings.
Example Python code of the MD5 Brutef
- Crash Course Computer Science
- Start here.
Check out the first two books but download the Intel Software Manuals and use as references.
- Assembly Language Step by Step
- Easy introduction to Assembly Language
- Assembly Language for X86 Processors by Kip Irvine
| def get_to_xrefs(ea): | |
| xref_set = set([]) | |
| for xref in idautils.XrefsTo(ea, 1): | |
| xref_set.add(xref) | |
| return xref_set | |
| def get_from_xrefs(ea): | |
| xref_set = set([]) | |
| for xref in idautils.XrefsTo(ea, 1): | |
| xref_set.add(xref) |
| import idautils | |
| JMPS = [idaapi.NN_jmp, idaapi.NN_jmpfi, idaapi.NN_jmpni] | |
| CALLS = [idaapi.NN_call, idaapi.NN_callfi, idaapi.NN_callni] | |
| DEBUG = True | |
| COMMENT = True | |
| class CSP(): | |
| pass |
| import base64 | |
| from Crypto.Cipher import ARC4 | |
| def str_decrypt(enc_data): | |
| key = 'fuckav\x00' | |
| cipher = ARC4.new(key) | |
| try: | |
| enc_data = base64.b64decode(enc_data) | |
| except: | |
| return enc_data |
| import idautils | |
| import operator | |
| JMPS = [eval("idaapi."+name) for name in dir(idaapi) if "NN_j" in name] | |
| def get_riat_func(): | |
| gpa = idc.get_name_ea_simple("GetProcAddress") | |
| func_gpa = {} | |
| for tt in idautils.XrefsTo(gpa, 0): | |
| if tt.type != 3: # Data_Read: |
| import idautils | |
| comments = {} | |
| for func in idautils.Functions(): | |
| flags = idc.get_func_attr(func, FUNCATTR_FLAGS) # skip library & thunk functions | |
| if flags & FUNC_LIB or flags & FUNC_THUNK: | |
| continue | |
| dism_addr = list(idautils.FuncItems(func)) | |
| for ea in dism_addr: | |
| temp = idc.get_cmt(ea, 0) | |
| if temp: |