From b4ea75e67706f0c2064ee482be0f3e2aed55ee51 Mon Sep 17 00:00:00 2001 From: wargio Date: Wed, 4 Dec 2024 06:55:00 +0000 Subject: [PATCH] deploy: 2aef43b68a1a2d92461873db487a59219d2a9615 --- index.html | 246 +-- search.json | 1201 +++++------ sitemap.xml | 276 +-- src/acknowledgments/credits.html | 256 +-- src/analysis/calling_conventions.html | 258 +-- src/analysis/code_analysis.html | 324 +-- src/analysis/cpu_platform_profiles.html | 290 +-- src/analysis/emulation.html | 264 +-- src/analysis/graphs.html | 306 +-- src/analysis/intro.html | 258 +-- src/analysis/signatures.html | 276 +-- src/analysis/symbols.html | 258 +-- src/analysis/syscalls.html | 258 +-- src/analysis/types.html | 288 +-- src/analysis/variables.html | 264 +-- src/analysis/vtables.html | 258 +-- src/basic_commands/block_size.html | 258 +-- src/basic_commands/comparing_bytes.html | 258 +-- src/basic_commands/dietline.html | 318 +-- src/basic_commands/flags.html | 270 +-- src/basic_commands/intro.html | 262 +-- src/basic_commands/mapping_files.html | 258 +-- src/basic_commands/print_modes.html | 336 +-- src/basic_commands/sdb.html | 276 +-- src/basic_commands/sections.html | 258 +-- src/basic_commands/seeking.html | 270 +-- src/basic_commands/write.html | 264 +-- src/basic_commands/yank_paste.html | 258 +-- src/configuration/colors.html | 246 +-- ...ables.html => compile_time_variables.html} | 268 +-- src/configuration/evars.html | 246 +-- src/configuration/initial_scripts.html | 252 +-- src/configuration/intro.html | 246 +-- src/configuration/run_time_variables.html | 1822 +++++++++++++++++ src/crackmes/avatao/01-reverse4/bytecode.html | 258 +-- .../avatao/01-reverse4/first_steps.html | 258 +-- .../avatao/01-reverse4/instructionset.html | 258 +-- src/crackmes/avatao/01-reverse4/intro.html | 258 +-- src/crackmes/avatao/01-reverse4/main.html | 258 +-- src/crackmes/avatao/01-reverse4/outro.html | 258 +-- src/crackmes/avatao/01-reverse4/rizin.html | 258 +-- src/crackmes/avatao/01-reverse4/vmloop.html | 258 +-- .../hackthebox/find-the-easy-pass/bonus.html | 258 +-- .../find-the-validation-routine.html | 258 +-- .../fire-up-the-debugger.html | 258 +-- .../find-the-easy-pass/identification.html | 258 +-- .../hackthebox/find-the-easy-pass/intro.html | 258 +-- src/crackmes/hackthebox/intro.html | 258 +-- src/crackmes/intro.html | 258 +-- src/crackmes/ioli/intro.html | 258 +-- src/crackmes/ioli/ioli_0x00.html | 258 +-- src/crackmes/ioli/ioli_0x01.html | 258 +-- src/crackmes/ioli/ioli_0x02.html | 258 +-- src/crackmes/ioli/ioli_0x03.html | 258 +-- src/crackmes/ioli/ioli_0x04.html | 258 +-- src/crackmes/ioli/ioli_0x05.html | 258 +-- src/crackmes/ioli/ioli_0x06.html | 258 +-- src/crackmes/ioli/ioli_0x07.html | 264 +-- src/crackmes/ioli/ioli_0x08.html | 258 +-- src/crackmes/ioli/ioli_0x09.html | 258 +-- src/debugger/apple.html | 270 +-- src/debugger/files.html | 258 +-- src/debugger/getting_started.html | 264 +-- src/debugger/heap.html | 258 +-- src/debugger/intro.html | 258 +-- src/debugger/memory_maps.html | 258 +-- src/debugger/migration.html | 306 +-- src/debugger/registers.html | 258 +-- src/debugger/revdebug.html | 258 +-- src/debugger/windows_messages.html | 258 +-- src/disassembling/adding_metadata.html | 258 +-- src/disassembling/esil.html | 376 ++-- src/disassembling/intro.html | 258 +-- src/first_steps/basic_debugger_session.html | 246 +-- src/first_steps/commandline_options.html | 246 +-- src/first_steps/commandline_rizin.html | 246 +-- src/first_steps/contributing.html | 246 +-- src/first_steps/expressions.html | 246 +-- src/first_steps/intro.html | 246 +-- src/introduction/compilation_android.html | 246 +-- src/introduction/compilation_portability.html | 246 +-- src/introduction/getting_rizin.html | 246 +-- src/introduction/overview.html | 246 +-- src/introduction/windows_compilation.html | 246 +-- src/plugins/debug.html | 258 +-- src/plugins/dev-analysis.html | 258 +-- src/plugins/dev-asm.html | 264 +-- src/plugins/dev-bin.html | 270 +-- src/plugins/dev-other.html | 270 +-- src/plugins/intro.html | 276 +-- src/plugins/ioplugins.html | 258 +-- src/plugins/python.html | 264 +-- src/plugins/rz-pm.html | 258 +-- src/plugins/testing.html | 258 +-- src/refcard/intro.html | 312 +-- src/remote_access/remote_gdb.html | 258 +-- src/remote_access/remoting_capabilities.html | 258 +-- src/remote_access/windbg.html | 312 +-- src/scripting/intro.html | 258 +-- src/scripting/loops.html | 258 +-- src/scripting/macros.html | 264 +-- src/scripting/rz-pipe.html | 294 +-- src/search_bytes/automation.html | 258 +-- src/search_bytes/backward_search.html | 258 +-- src/search_bytes/basic_searches.html | 258 +-- .../configurating_the_search.html | 258 +-- src/search_bytes/intro.html | 258 +-- src/search_bytes/pattern_search.html | 258 +-- src/search_bytes/search_in_assembly.html | 258 +-- src/search_bytes/searching_aes_keys.html | 258 +-- src/tools/intro.html | 258 +-- src/tools/rz-asm/assemble.html | 264 +-- src/tools/rz-asm/config.html | 258 +-- src/tools/rz-asm/disassemble.html | 282 +-- src/tools/rz-asm/intro.html | 271 +-- src/tools/rz-ax/intro.html | 258 +-- src/tools/rz-bin/entrypoints.html | 258 +-- src/tools/rz-bin/exports.html | 258 +-- src/tools/rz-bin/file_identification.html | 258 +-- src/tools/rz-bin/imports.html | 258 +-- src/tools/rz-bin/intro.html | 283 +-- src/tools/rz-bin/libraries.html | 258 +-- src/tools/rz-bin/program_sections.html | 258 +-- src/tools/rz-bin/strings.html | 258 +-- src/tools/rz-bin/symbols.html | 258 +-- src/tools/rz-diff/binary_diffing.html | 342 ++-- src/tools/rz-diff/intro.html | 258 +-- src/tools/rz-find/intro.html | 258 +-- src/tools/rz-gg/lang.html | 396 ++-- src/tools/rz-gg/rz-gg.html | 276 +-- src/tools/rz-hash/intro.html | 276 +-- src/tools/rz-hash/rz-hash_tool.html | 258 +-- src/tools/rz-run/intro.html | 258 +-- src/visual_mode/intro.html | 276 +-- src/visual_mode/visual_assembler.html | 258 +-- .../visual_configuration_editor.html | 258 +-- src/visual_mode/visual_disassembly.html | 358 ++-- src/visual_mode/visual_panels.html | 312 +-- 138 files changed, 20944 insertions(+), 18295 deletions(-) rename src/configuration/{build_variables.html => compile_time_variables.html} (97%) create mode 100644 src/configuration/run_time_variables.html diff --git a/index.html b/index.html index c56504c6..000dbd70 100644 --- a/index.html +++ b/index.html @@ -270,8 +270,14 @@ + @@ -288,73 +294,73 @@ @@ -371,31 +377,31 @@ @@ -412,49 +418,49 @@ @@ -471,19 +477,19 @@ @@ -500,73 +506,73 @@ @@ -583,25 +589,25 @@ @@ -618,61 +624,61 @@ @@ -689,19 +695,19 @@ @@ -718,139 +724,139 @@ @@ -867,61 +873,61 @@ @@ -938,157 +944,157 @@ @@ -1105,7 +1111,7 @@ @@ -1122,7 +1128,7 @@ diff --git a/search.json b/search.json index a030e437..3eae68a1 100644 --- a/search.json +++ b/search.json @@ -283,2291 +283,2302 @@ ] }, { - "objectID": "src/configuration/build_variables.html", - "href": "src/configuration/build_variables.html", - "title": "16  Build Variables", + "objectID": "src/configuration/compile_time_variables.html", + "href": "src/configuration/compile_time_variables.html", + "title": "16  Compile-Time Variables", "section": "", - "text": "When rizin is built from sources, some build variables will be hardcoded within the rizin libraries.\nThese build variables can be accessed by executing the command rizin -H on a terminal.\n$ rizin -H\nRZ_VERSION=X.Y.Z\nRZ_PREFIX=/usr\nRZ_EXTRA_PREFIX=\nRZ_MAGICPATH=/usr/share/rizin/magic\nRZ_INCDIR=/usr/include/librz\nRZ_LIBDIR=/usr/lib\nRZ_SIGDB=/usr/share/rizin/sigdb\nRZ_EXTRA_SIGDB=\nRZ_LIBEXT=so\nRZ_CONFIGHOME=/home/username/.config/rizin\nRZ_DATAHOME=/home/username/.local/share/rizin\nRZ_CACHEHOME=/home/username/.cache/rizin\nRZ_LIB_PLUGINS=/usr/lib/rizin/plugins\nRZ_EXTRA_PLUGINS=\nRZ_USER_PLUGINS=/home/username/.local/lib/rizin/plugins\nRZ_IS_PORTABLE=0\nYou can also view a specific build variable by executing -H variable.\nFor example:\n$ rizin -H RZ_USER_PLUGINS\n/home/username/.local/lib/rizin/plugins", + "text": "When rizin is built from sources, some compile-time variables will be hardcoded within the rizin libraries.\nThese compile-time variables can be accessed by executing the command rizin -H on a terminal.\n$ rizin -H\nRZ_VERSION=X.Y.Z\nRZ_PREFIX=/usr\nRZ_EXTRA_PREFIX=\nRZ_MAGICPATH=/usr/share/rizin/magic\nRZ_INCDIR=/usr/include/librz\nRZ_LIBDIR=/usr/lib\nRZ_SIGDB=/usr/share/rizin/sigdb\nRZ_EXTRA_SIGDB=\nRZ_LIBEXT=so\nRZ_CONFIGHOME=/home/username/.config/rizin\nRZ_DATAHOME=/home/username/.local/share/rizin\nRZ_CACHEHOME=/home/username/.cache/rizin\nRZ_LIB_PLUGINS=/usr/lib/rizin/plugins\nRZ_EXTRA_PLUGINS=\nRZ_USER_PLUGINS=/home/username/.local/lib/rizin/plugins\nRZ_IS_PORTABLE=0\nYou can also view a specific compile-time variable by executing -H variable.\nFor example:\n$ rizin -H RZ_USER_PLUGINS\n/home/username/.local/lib/rizin/plugins", "crumbs": [ "Configuration", - "16  Build Variables" + "16  Compile-Time Variables" + ] + }, + { + "objectID": "src/configuration/run_time_variables.html", + "href": "src/configuration/run_time_variables.html", + "title": "17  Run-Time Variables", + "section": "", + "text": "Run-time variables (also known as environment variables) can be used to change the default behavior when running rizin or tools.\nThe description of these run-time variables can be accessed by executing the command rizin -hh on a terminal.\n$ rizin -hh\n...\nPlugins:\n binrc /home/username/.local/share/rizin/rc.d/bin-<format> (elf, elf64, mach0, ..)\n RZ_USER_PLUGINS /home/username/.local/lib/rizin/plugins\n RZ_LIB_PLUGINS /home/username/.local/lib/rizin/plugins\n RZ_EXTRA_PLUGINS\nEnvironment:\n ANSICON ansicon's W & H of the buffer and w & h of the window in the form of: \"WxH (wxh)\"\n DEBUGINFOD_URLS e bin.dbginfo.debuginfod_urls - use alternative debuginfod server\n COLUMNS terminal columns to use\n RZ_ABORTLEVEL target log level/severity when to abort (0:DEBUG, 1:VERBOSE, 2:INFO, 3:WARN, 4:ERROR, 5:FATAL)\n RZ_CURL whether to use curl (for SSL support)\n RZ_DEBUG if defined, show error messages and crash signal\n RZ_DEBUG_ASSERT set a breakpoint when hitting an assert\n RZ_DEBUG_TOOL debug tool to use when showing error messages and crash signal\n RZ_DYLDCACHE_FILTER dyld cache filter (MacOS dynamic libraries location(s) at runtime)\n RZ_HTTP_AUTHFILE HTTP Authentification user file\n RZ_LOGCOLORS should the log output use colors\n RZ_LOGFILE logging output filename/path\n RZ_LOGLEVEL target log level/severity (0:DEBUG, 1:VERBOSE, 2:INFO, 3:WARN, 4:ERROR, 5:FATAL)\n RZ_LOGSHOWSOURCES should the log output contain src info (filename:lineno)\n RZ_PIPE_IN rzpipe cmd input (file descriptor)\n RZ_PIPE_OUT rzpipe cmd output (file descriptor)\n RZ_MAGICPATH /home/username/.local/share/rizin/magic\n RZ_NOPLUGINS do not load rizin shared plugins\n RZ_RCFILE /home/username/.rizinrc (user preferences, batch script)\n RZ_DATAHOME /home/username/.local/share/rizin\n RZ_VERSION contains the current version of rizin\n SFLIBPATH SFLib syscall library path\nPaths:\n RZ_PREFIX /home/username/.local\n RZ_EXTRA_PREFIX\n RZ_INCDIR /home/username/.local/include/librz\n RZ_LIBDIR /home/username/.local/lib\n RZ_SIGDB /home/username/.local/share/rizin/sigdb\n RZ_EXTRA_SIGDB\n RZ_LIBEXT so", + "crumbs": [ + "Configuration", + "17  Run-Time Variables" ] }, { "objectID": "src/basic_commands/intro.html", "href": "src/basic_commands/intro.html", - "title": "17  Basic Commands", + "title": "18  Basic Commands", "section": "", "text": "Most command names in rizin are derived from action names. They should be easy to remember, as they are short. Actually, all commands are single letters. Subcommands or related commands are specified using the second character of the command name. For example, / foo is a command to search plain string, while /x 90 90 is used to look for hexadecimal pairs.\nThe general format for a valid command (as explained in the Rizin Command-line chapter) looks like this:\n[.][times][cmd][~grep][@[@iter]addr!size][|>pipe] ; ...\nFor example,\n> 3s +1024 ; seeks three times 1024 from the current seek\nIf a command starts with R!, the rest of the string is passed to the currently loaded IO plugin (a debugger, for example). Most plugins provide help messages with R!? or R!help.\n$ rizin -d /bin/ls\n> R!help ; handled by the IO plugin\nIf a command starts with !, posix_system() is called to pass the command to your shell. Check !? for more options and usage examples.\n> !ls ; run `ls` in the shell\nThe meaning of the arguments (iter, addr, size) depends on the specific command. As a rule of thumb, most commands take a number as an argument to specify the number of bytes to work with, instead of the currently defined block size. Some commands accept math expressions or strings.\n> px 0x17 ; show 0x17 bytes in hexs at current seek\n> s base+0x33 ; seeks to flag 'base' plus 0x33\n> / lib ; search for 'lib' string.\nThe @ sign is used to specify a temporary offset location or a seek position at which the command is executed, instead of current seek position. This is quite useful as you don’t have to seek around all the time.\n> p8 10 @ 0x4010 ; show 10 bytes at offset 0x4010\n> f patata @ 0x10 ; set 'patata' flag at offset 0x10\nUsing @@ sub-commands you can execute a single command on a list of flags, functions, symbols, etc. You can think of these as foreach operations:\n> s 0\n> / lib ; search 'lib' string\n> p8 20 @@f:hit0_* ; show 20 hexpairs at each search hit\nThe > operation is used to redirect the output of a command into a file (overwriting it if it already exists).\n> pr > dump.bin ; dump 'raw' bytes of current block to file named 'dump.bin'\n> f > flags.txt ; dump flag list to 'flags.txt'\nThe | operation (pipe) is similar to what you are used to expect from it in a *NIX shell: an output of one command as input to another.\n[0x4A13B8C0]> f | grep section | grep text\n0x0805f3b0 512 section._text\n0x080d24b0 512 section._text_end\nYou can pass several commands in a single line by separating them with a semicolon ;:\n> px ; dr\nUsing _, you can print the result that was obtained by the last command.\n[0x00001060]> axt 0x00002004\nmain 0x1181 [DATA] lea rdi, str.argv__2d_:__s\n[0x00001060]> _\nmain 0x1181 [DATA] lea rdi, str.argv__2d_:__s", "crumbs": [ "Basic Commands", - "17  Basic Commands" + "18  Basic Commands" ] }, { "objectID": "src/basic_commands/seeking.html", "href": "src/basic_commands/seeking.html", - "title": "18  Seeking", + "title": "19  Seeking", "section": "", - "text": "18.1 Open file\nTo move around the file we are inspecting we will need to change the offset at which we are using the s command.\nThe argument is a math expression that can contain flag names, parenthesis, addition, subtraction, multiplication of immediate of contents of memory using brackets.\nSome example commands:\nObserve how the prompt offset changes. The first line moves the current offset to the address 0x10.\nThe second does a relative seek 4 bytes forward.\nAnd finally, the last 2 commands are undoing, and redoing the last seek operations in the seek history.\nInstead of using just numbers, we can use complex expressions, or basic arithmetic operations to represent the address to seek.\nTo do this, check the ?$? Help message which describes the internal variables that can be used in the expressions. For example, this is the same as doing sd +4 .\nFrom the debugger (or when emulating) we can also use the register names as references. They are loaded as flags with the .dr* command, which happens under the hood.\nHere’s the full help of the s command. We will explain in more detail below.\nIf you want to inspect the result of a math expression, you can evaluate it using the ? command. Simply pass the expression as an argument. The result can be displayed in hexadecimal, decimal, octal or binary formats.\nThere are also subcommands of % that display the output in one specific format (base 10, base 16 ,…). See %v for instance.\nIn the visual mode, you can press u (undo) or U (redo) inside the seek history to return back to previous or forward to the next location.\nAs a test file, let’s use a simple hello_world compiled in Linux ELF 64-bit format:\nAfter we compile it with gcc -o hello_world hello_world.c let’s open it with rizin:\nNow we have the command prompt:\nAnd it is time to go deeper.", + "text": "19.1 Open file\nTo move around the file we are inspecting we will need to change the offset at which we are using the s command.\nThe argument is a math expression that can contain flag names, parenthesis, addition, subtraction, multiplication of immediate of contents of memory using brackets.\nSome example commands:\nObserve how the prompt offset changes. The first line moves the current offset to the address 0x10.\nThe second does a relative seek 4 bytes forward.\nAnd finally, the last 2 commands are undoing, and redoing the last seek operations in the seek history.\nInstead of using just numbers, we can use complex expressions, or basic arithmetic operations to represent the address to seek.\nTo do this, check the ?$? Help message which describes the internal variables that can be used in the expressions. For example, this is the same as doing sd +4 .\nFrom the debugger (or when emulating) we can also use the register names as references. They are loaded as flags with the .dr* command, which happens under the hood.\nHere’s the full help of the s command. We will explain in more detail below.\nIf you want to inspect the result of a math expression, you can evaluate it using the ? command. Simply pass the expression as an argument. The result can be displayed in hexadecimal, decimal, octal or binary formats.\nThere are also subcommands of % that display the output in one specific format (base 10, base 16 ,…). See %v for instance.\nIn the visual mode, you can press u (undo) or U (redo) inside the seek history to return back to previous or forward to the next location.\nAs a test file, let’s use a simple hello_world compiled in Linux ELF 64-bit format:\nAfter we compile it with gcc -o hello_world hello_world.c let’s open it with rizin:\nNow we have the command prompt:\nAnd it is time to go deeper.", "crumbs": [ "Basic Commands", - "18  Seeking" + "19  Seeking" ] }, { "objectID": "src/basic_commands/seeking.html#open-file", "href": "src/basic_commands/seeking.html#open-file", - "title": "18  Seeking", + "title": "19  Seeking", "section": "", "text": "#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n/*\n * This is simple hello_world program made for education purposes.\n * Licensed under CC-BY-SA 4.0 license.\n *\n * In order to compile executable run:\n *\n * gcc -o hello_world hello_world.c\n *\n */\n\nint main(int argc, char* argv[]) {\n const char *str1 = \"Hello \";\n const char *str2 = \"world!\";\n\n size_t str1_size = strlen(str1);\n size_t str2_size = strlen(str2);\n\n char *output = malloc(str1_size + str2_size + 1);\n if (output) {\n strcpy(output, str1);\n strcat(output, str2);\n\n puts(output);\n free(output);\n }\n\n return 0;\n}\n\n$ rizin hello_world\n\n[0x00001100]>", "crumbs": [ "Basic Commands", - "18  Seeking" + "19  Seeking" ] }, { "objectID": "src/basic_commands/seeking.html#seeking-at-any-position", "href": "src/basic_commands/seeking.html#seeking-at-any-position", - "title": "18  Seeking", - "section": "18.2 Seeking at any position", - "text": "18.2 Seeking at any position\nAll seeking commands that take an address as a command parameter can use any numeral base such as hex, octal, binary or decimal.\nSeek to an address 0x0. An alternative command is simply 0x0\n[0x00001100]> s 0x0\n[0x00000000]>\nPrint current address:\n[0x00000000]> s\n0x0\n[0x00000000]>\nThere is an alternate way to print current position: %v $$.\nSeek N positions forward, space is optional:\n[0x00000000]> sd 128\n[0x00000080]>\nUndo last two seeks to return to the initial address:\n[0x00000080]> shu\n[0x00000000]> shu\n[0x00001100]>\nWe are back at 0x00001100.\nThere’s also a command to show the seek history:\n[0x00001100]> sh\n0x1100 entry0 # current seek\n0x0 segment.LOAD0 # redo\n0x80 segment.PHDR+64 # redo\n[0x00400410]> sh*\n# Current seek @ 0x1100\nf redo_0 @ 0x0\nf redo_1 @ 0x80", + "title": "19  Seeking", + "section": "19.2 Seeking at any position", + "text": "19.2 Seeking at any position\nAll seeking commands that take an address as a command parameter can use any numeral base such as hex, octal, binary or decimal.\nSeek to an address 0x0. An alternative command is simply 0x0\n[0x00001100]> s 0x0\n[0x00000000]>\nPrint current address:\n[0x00000000]> s\n0x0\n[0x00000000]>\nThere is an alternate way to print current position: %v $$.\nSeek N positions forward, space is optional:\n[0x00000000]> sd 128\n[0x00000080]>\nUndo last two seeks to return to the initial address:\n[0x00000080]> shu\n[0x00000000]> shu\n[0x00001100]>\nWe are back at 0x00001100.\nThere’s also a command to show the seek history:\n[0x00001100]> sh\n0x1100 entry0 # current seek\n0x0 segment.LOAD0 # redo\n0x80 segment.PHDR+64 # redo\n[0x00400410]> sh*\n# Current seek @ 0x1100\nf redo_0 @ 0x0\nf redo_1 @ 0x80", "crumbs": [ "Basic Commands", - "18  Seeking" + "19  Seeking" ] }, { "objectID": "src/basic_commands/block_size.html", "href": "src/basic_commands/block_size.html", - "title": "19  Block Size", + "title": "20  Block Size", "section": "", "text": "The block size determines how many bytes rizin commands will process when not given an explicit size argument. You can temporarily change the block size by specifying a numeric argument to the print commands. For example px 20.\n[0x00000000]> b?\nUsage: b[j*-+fm] # Display or change the block size\n| b[j*] [<num>] # Set/Get current block size\n| b- <num> # Decrease current block size\n| b+ <num> # Increase current block size\n| bf <flag> # Set block size to flag size\n| bm [<num>] # Set/Get max block size\nThe b command is used to change the block size:\n[0x00000000]> b 0x100 # block size = 0x100\n[0x00000000]> b+16 # ... = 0x110\n[0x00000000]> b-32 # ... = 0xf0\nThe bf command is used to change the block size to value specified by a flag. For example, in symbols, the block size of the flag represents the size of the function. To make that work, you have to either run function analysis af (which is included in aa) or manually seek and define some functions e.g. via Vd.\n[0x00000000]> bf sym.main # block size = sizeof(sym.main)\n[0x00000000]> pD @ sym.main # disassemble sym.main\nYou can combine two operations in a single pdf command. Except that pdf neither uses nor affects global block size.\n[0x00000000]> pdf @ sym.main # disassemble sym.main\nAnother way around is to use special variables $FB and $FS which denote Function’s Beginning and Size at the current seek. Read more about Usable variables.\n[0x00000000]> s sym.main + 0x04\n[0x00001ec9]> pD @ $FB !$FS # disassemble current function\n╭ 211: int main (int argc, char **argv, char **envp);\n│ 0x00001ec5 55 push rbp\n│ 0x00001ec6 4889e5 mov rbp, rsp\n│ 0x00001ec9 4881ecc0000000 sub rsp, 0xc0\n...\n╰ 0x00001f97 c3 ret\nNote: don’t put space after ! size designator. See also Rizin Command-line.", "crumbs": [ "Basic Commands", - "19  Block Size" + "20  Block Size" ] }, { "objectID": "src/basic_commands/sections.html", "href": "src/basic_commands/sections.html", - "title": "20  Sections", + "title": "21  Sections", "section": "", "text": "The concept of sections is tied to the information extracted from the binary. We can display this information by using the i command.\nDisplaying information about sections:\n[0x00001100]> iS\npaddr size vaddr vsize align perm name type flags \n-----------------------------------------------------------------------------------------\n0x00000000 0x0 ---------- 0x0 0x0 ---- NULL \n0x00000318 0x1c 0x00000318 0x1c 0x0 -r-- .interp PROGBITS alloc\n0x00000338 0x50 0x00000338 0x50 0x0 -r-- .note.gnu.property NOTE alloc\n0x00000388 0x20 0x00000388 0x20 0x0 -r-- .note.ABI-tag NOTE alloc\n0x000003a8 0x24 0x000003a8 0x24 0x0 -r-- .gnu.hash GNU_HASH alloc\n0x000003d0 0x120 0x000003d0 0x120 0x0 -r-- .dynsym DYNSYM alloc\n0x000004f0 0xae 0x000004f0 0xae 0x0 -r-- .dynstr STRTAB alloc\n0x0000059e 0x18 0x0000059e 0x18 0x0 -r-- .gnu.version VERSYM alloc\n0x000005b8 0x30 0x000005b8 0x30 0x0 -r-- .gnu.version_r VERNEED alloc\n0x000005e8 0xc0 0x000005e8 0xc0 0x0 -r-- .rela.dyn RELA alloc\n0x000006a8 0x90 0x000006a8 0x90 0x0 -r-- .rela.plt RELA alloc,info\n0x00001000 0x1b 0x00001000 0x1b 0x0 -r-x .init PROGBITS alloc,execute\n0x00001020 0x70 0x00001020 0x70 0x0 -r-x .plt PROGBITS alloc,execute\n0x00001090 0x10 0x00001090 0x10 0x0 -r-x .plt.got PROGBITS alloc,execute\n0x000010a0 0x60 0x000010a0 0x60 0x0 -r-x .plt.sec PROGBITS alloc,execute\n0x00001100 0x199 0x00001100 0x199 0x0 -r-x .text PROGBITS alloc,execute\n0x0000129c 0xd 0x0000129c 0xd 0x0 -r-x .fini PROGBITS alloc,execute\n0x00002000 0x12 0x00002000 0x12 0x0 -r-- .rodata PROGBITS alloc\n0x00002014 0x34 0x00002014 0x34 0x0 -r-- .eh_frame_hdr PROGBITS alloc\n0x00002048 0xac 0x00002048 0xac 0x0 -r-- .eh_frame PROGBITS alloc\n0x00002d90 0x8 0x00003d90 0x8 0x0 -rw- .init_array INIT_ARRAY write,alloc\n0x00002d98 0x8 0x00003d98 0x8 0x0 -rw- .fini_array FINI_ARRAY write,alloc\n0x00002da0 0x1f0 0x00003da0 0x1f0 0x0 -rw- .dynamic DYNAMIC write,alloc\n0x00002f90 0x70 0x00003f90 0x70 0x0 -rw- .got PROGBITS write,alloc\n0x00003000 0x10 0x00004000 0x10 0x0 -rw- .data PROGBITS write,alloc\n0x00003010 0x0 0x00004010 0x8 0x0 -rw- .bss NOBITS write,alloc\n0x00003010 0x65 ---------- 0x65 0x0 ---- .comment PROGBITS merge,strings\n0x00003078 0x2b8 ---------- 0x2b8 0x0 ---- .symtab SYMTAB \n0x00003330 0x18a ---------- 0x18a 0x0 ---- .strtab STRTAB \n0x000034ba 0x107 ---------- 0x107 0x0 ---- .shstrtab STRTAB \nAs you may know, binaries have sections and maps. The sections define the contents of a portion of the file that can be mapped in memory (or not). What is mapped is defined by the segments.\nFirmware images, bootloaders and binary files usually place various sections of a binary at different addresses in memory. To represent this behavior, rizin offers the iS. Use iS? to get the help message. To list all created sections use iS (or iSj to get the json format). The iS= will show the region bars in ascii-art.\nYou can create a new mapping using the om subcommand as follows:\nom fd vaddr [size] [paddr] [rwx] [name]\nFor Example:\n[0x00001100]> om 4 0x00000100 0x00400000 0x0001ae08 rwx test\nYou can also use oml command to view information about mapped sections:\n[0x00001100]> oml\n 1 fd: 4 +0x00000000 0x00004020 - 0x0000408f r-- vmap.reloc-targets\n 2 fd: 3 +0x00000000 0x00000000 - 0x00000737 r-- fmap.LOAD0\n 3 fd: 3 +0x00001000 0x00001000 - 0x000012a8 r-x fmap.LOAD1\n 4 fd: 3 +0x00002000 0x00002000 - 0x000020f3 r-- fmap.LOAD2\n 5 fd: 5 +0x00000000 0x00004010 - 0x00004017 rw- mmap.LOAD3\n 6 fd: 6 +0x00002d90 0x00003d90 - 0x0000400f r-- vmap.LOAD3\n 7 fd: 4 +0x0001ae08 0x00000100 * 0x004000ff r-x test\nUse om? to get all the possible subcommands. To list all the defined maps use oml (or omlj to get the json format). To get the ascii art view use oml=.\nIt is also possible to delete the mapped section using the om- mapid command.\nFor Example:\n[0x00001100]> om- 7", "crumbs": [ "Basic Commands", - "20  Sections" + "21  Sections" ] }, { "objectID": "src/basic_commands/mapping_files.html", "href": "src/basic_commands/mapping_files.html", - "title": "21  Mapping Files", + "title": "22  Mapping Files", "section": "", "text": "Rizin’s I/O subsystem allows you to map the contents of files into the same I/O space used to contain a loaded binary. New contents can be placed at random offsets.\nThe o command permits the user to open a file, this is mapped at offset 0 unless it has a known binary header and then the maps are created in virtual addresses.\nSometimes, we want to rebase a binary, or maybe we want to load or map the file in a different address.\nWhen launching rizin, the base address can be changed with the -B flag. But you must notice the difference when opening files with unknown headers, like bootloaders, so we need to map them using the -m flag (or specifying it as argument to the o command).\nRizin is able to open files and map portions of them at random places in memory specifying attributes like permissions and name. It is the perfect basic tooling to reproduce an environment like a core file, a debug session, by also loading and mapping all the libraries the binary depends on.\nOpening files (and mapping them) is done using the o (open) command. Let’s read the help:\n[0x00000000]> o?\nUsage: o[?] # Open files and handle opened files\n| o <file> [<addr> [<perm>]] # Open <file>\n| o+ <file> [<addr> [<perm>]] # Open <file> in write mode\n| ol[jqt] # List opened files\n| ol.[jqt] # Show currently opened file\n| o- <fd> # Close file descriptor\n| o-- # Close all files\n| oc <file> # Close all opened files and open <file>, like relaunching rizin\n| oC <len> # Open a 'malloc://<len>' file, copying the bytes from current offset\n| on[+] # Open files without parsing binary info\n| oo[+bcdmn?] # Reopen current file\n| oL[jqt] [<path>] # List all IO plugins / Register IO plugin from <path>\n| o= # List opened files in ASCII-art bars\n| oa <arch> <bits> [<filename>] # Specify <arch> and <bits> for the file <filename> or the current one if none is specified\n| ob[?] # Handle binary files\n| ou <fd> # Use specified <fd>\n| op[npr] # Select prioritized file\n| om[?] # Handle IO maps\n| ox <fd> <fdx> # Exchange the descs of <fd> and <fdx> and keep the mapping\nPrepare a simple layout:\n$ rz-bin -l hello_world\n[Libs]\nlibrary \n----------\nlibc.so.6\nMap a file:\n[0x00001100]> o /bin/sh 0x499999\nList mapped files:\n[0x00000000]> ol\n 3 - r-x 0x00003d48 /home/user/playground/book/examples/hello_world/hello_world\n 4 - r-x 0x00000070 vfile://0/reloc-targets\n 5 - rw- 0x00000008 null://8\n 6 - r-x 0x00003d48 vfile://0/patched\n 7 * r-x 0x000d5b68 /bin/sh\n 8 - r-- 0x00000bf0 vfile://1/reloc-targets\n 9 - rw- 0x0000ed7c null://60796\n10 - r-- 0x000d5b68 vfile://1/patched\nNote: vfile is a virtual file, that is often automatically created to patch relocations and could also be created manually, if needed. It was created to avoid modifying the original file/IO ranges.\nPrint hexadecimal values from /bin/sh:\n[0x00000000]> px @ 0x499999\nUnmap files using the o- command. Pass the required file descriptor to it as an argument:\n[0x00000000]> o- 7\nYou can also view the ascii table showing the list of the opened files:\n[0x00000000]> o=", "crumbs": [ "Basic Commands", - "21  Mapping Files" + "22  Mapping Files" ] }, { "objectID": "src/basic_commands/print_modes.html", "href": "src/basic_commands/print_modes.html", - "title": "22  Print Modes", + "title": "23  Print Modes", "section": "", - "text": "One of the key features of Rizin is displaying information in many formats. The goal is to offer a selection of display choices to interpret binary data in the best possible way.\nBinary data can be represented as integers, shorts, longs, floats, timestamps, hexpair strings, or more complex formats like C structures, disassembly listings, decompilation listing, be a result of an external processing…\nBelow is a list of available print modes listed by p?:\n[0x00001100]> p?\nUsage: p[=68abcdDfiImrstuxz] [arg|len] [@addr] \n| p[b|B|xb] [len] ([S]) bindump N bits skipping S bytes\n| p[iI][df] [len] print N ops/bytes (f=func) (see pi? and pdq)\n| p[kK] [len] print key in randomart (K is for mosaic)\n| p-[?][jh] [mode] bar|json|histogram blocks (mode: e?search.in)\n| p2 [len] 8x8 2bpp-tiles\n| p6[de] [len] base64 decode/encode\n| p8[?][j] [len] 8bit hexpair list of bytes\n| p=[?][bep] [N] [L] [b] show entropy/printable chars/chars bars\n| pa[edD] [arg] pa:assemble pa[dD]:disasm or pae: esil from hex\n| pb[?] [n] bitstream of N bits\n| pB[?] [n] bitstream of N bytes\n| pc[?][p] [len] output C (or python) format\n| pC[aAcdDxw] [rows] print disassembly in columns (see hex.cols and pdq)\n| pd[?] [sz] [a] [b] disassemble N opcodes (pd) or N bytes (pD)\n| pf[?][.nam] [fmt] print formatted data (pf.name, pf.name $<expr>)\n| pF[?][apx] print asn1, pkcs7 or x509\n| pg[?][x y w h] [cmd] create new visual gadget or print it (see pg? for details)\n| ph[?][=|hash] ([len]) calculate hash for a block\n| pi[?][bdefrj] [num] print instructions\n| pI[?][iI][df] [len] print N instructions/bytes (f=func)\n| pj[?] [len] print as indented JSON\n| pm[?] [magic] print libmagic data (see pm? and /m?)\n| po[?] hex print operation applied to block (see po?)\n| pp[?][sz] [len] print patterns, see pp? for more help\n| pr[?][glx] [len] print N raw bytes (in lines or hexblocks, 'g'unzip)\n| ps[?][pwz] [len] print pascal/wide/zero-terminated strings\n| pt[?][dn] [len] print different timestamps\n| pu[?][w] [len] print N url encoded bytes (w=wide)\n| pv[?][jh] [mode] show variable/pointer/value in memory\n| px[?][owq] [len] hexdump of N bytes (o=octal, w=32bit, q=64bit)\n| plf print the RzIL output of the function\nTip: when using json output, you can append the ~{} to the command to get a pretty-printed version of the output:\n[0x00000000]> olj\n[{\"raised\":false,\"fd\":563280,\"uri\":\"malloc://512\",\"from\":0,\"writable\":true,\"size\":512,\"overlaps\":false}]\n[0x00000000]> olj~{}\n[\n {\n \"raised\": false,\n \"fd\": 563280,\n \"uri\": \"malloc://512\",\n \"from\": 0,\n \"writable\": true,\n \"size\": 512,\n \"overlaps\": false\n }\n]\nFor more on the magical powers of ~ see the help in ?@?, and the Rizin Command-line chapter earlier in the book.\n\n22.0.1 Hexadecimal View\npx gives a user-friendly output showing 16 pairs of numbers per row with offsets and raw representations:\n[0x00001100]> px\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\n0x00001100 f30f 1efa 31ed 4989 d15e 4889 e248 83e4 ....1.I..^H..H..\n0x00001110 f050 5445 31c0 31c9 488d 3dca 0000 00ff .PTE1.1.H.=.....\n0x00001120 15b3 2e00 00f4 662e 0f1f 8400 0000 0000 ......f.........\n\n22.0.1.1 Show Hexadecimal Words Dump (32 bits)\n[0x00001100]> pxw\n0x00001100 0xfa1e0ff3 0x8949ed31 0x89485ed1 0xe48348e2 ....1.I..^H..H..\n0x00001110 0x455450f0 0xc931c031 0xca3d8d48 0xff000000 .PTE1.1.H.=.....\n0x00001120 0x002eb315 0x2e66f400 0x00841f0f 0x00000000 ......f.........\n\n[0x00001100]> e cfg.bigendian\nfalse\n\n[0x00001100]> e cfg.bigendian=true\n\n[0x00001100]> pxw\n0x00001100 0xf30f1efa 0x31ed4989 0xd15e4889 0xe24883e4 ....1.I..^H..H..\n0x00001110 0xf0505445 0x31c031c9 0x488d3dca 0x000000ff .PTE1.1.H.=.....\n0x00001120 0x15b32e00 0x00f4662e 0x0f1f8400 0x00000000 ......f.........\n\n[0x00001100]> e cfg.bigendian=false\n\n\n22.0.1.2 8 bits Hexpair List of Bytes\n[0x00001100]> p8 16\nf30f1efa31ed4989d15e4889e24883e4\n\n\n22.0.1.3 Show Hexadecimal Quad-words Dump (64 bits)\n[0x00001100]> pxq\n0x00001100 0x8949ed31fa1e0ff3 0xe48348e289485ed1 ....1.I..^H..H..\n0x00001110 0xc931c031455450f0 0xff000000ca3d8d48 .PTE1.1.H.=.....\n0x00001120 0x2e66f400002eb315 0x0000000000841f0f ......f.........\n0x00001130 0x4800002ed93d8d48 0x394800002ed2058d H.=....H......H9\n\n\n\n22.0.2 Date/Time Formats\nCurrently supported timestamp output modes are:\n[0x00404888]> pt?\nUsage: pt[.dhn] # Print timestamps\n| pt # Print UNIX epoch time (32 bit `cfg.bigendian`, since January 1, 1970)\n| pt. # Print the current time\n| ptd # Print MS-DOS time (32 bit `cfg.bigendian`, since January 1, 1980)\n| pth # Print Mac HFS time (32 bit `cfg.bigendian`, since January 1, 1904)\n| ptn # Print NTFS time (64 bit `cfg.bigendian`, since January 1, 1601)\nFor example, you can ‘view’ the current buffer as timestamps in the ntfs time:\n[0x08048000]> e cfg.bigendian=false\n[0x08048000]> pt 4\n29:04:32948 23:12:36 +0000\n[0x08048000]> e cfg.bigendian=true\n[0x08048000]> pt 4\n20:05:13001 09:29:21 +0000\nAs you can see, the endianness affects the result. Once you have printed a timestamp, you can grep the output, for example, by year:\n[0x08048000]> pt ~1974 | wc -l\n15\n[0x08048000]> pt ~2022\n27:04:2022 16:15:43 +0000\nThe default date format can be configured using the cfg.datefmt variable. Formatting rules for it follow the well known strftime(3) format. Check the manpage for more details, but these are the most important:\n%a The abbreviated name of the day of the week according to the current locale.\n%A The full name of the day of the week according to the current locale.\n%d The day of the month as a decimal number (range 01 to 31).\n%D Equivalent to %m/%d/%y. (Yecch—for Americans only).\n%H The hour as a decimal number using a 24-hour clock (range 00 to 23).\n%I The hour as a decimal number using a 12-hour clock (range 01 to 12).\n%m The month as a decimal number (range 01 to 12).\n%M The minute as a decimal number (range 00 to 59).\n%p Either \"AM\" or \"PM\" according to the given time value.\n%s The number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). (TZ)\n%S The second as a decimal number (range 00 to 60). (The range is up to 60 to allow for occasional leap seconds.)\n%T The time in 24-hour notation (%H:%M:%S). (SU)\n%y The year as a decimal number without a century (range 00 to 99).\n%Y The year as a decimal number including the century.\n%z The +hhmm or -hhmm numeric timezone (that is, the hour and minute offset from UTC). (SU)\n%Z The timezone name or abbreviation.\n\n\n22.0.3 Basic Types\nThere are print modes available for all basic types. If you are interested in a more complex structure, type pf?? for format characters and pf??? for examples:\n[0x00499999]> pf??\nUsage: pf[j*q] <format> # Show data using given format string\n| pf <format> # Show data using given format string\n| pfj <format> # Show data using given format string (JSON mode)\n| pf* <format> # Show data using given format string (rizin mode)\n| pfq <format> # Show data using given format string (quiet mode)\n\nFormats:\n| b # byte (unsigned)\n| B # resolve enum bitfield (see t?)\n| c # char (signed byte)\n| C # byte in decimal\n| d # 0xHEX value (4 bytes) (see 'i' and 'x' formats)\n| D # disassemble one opcode\n| e # temporarily swap endian\n| E # resolve enum name (see t?)\n| f # float value (4 bytes)\n| F # double float value (8 bytes)\n| i # signed integer value (4 bytes) (see 'd' and 'x' formats)\n| n # next char specifies size of signed value (1, 2, 4, or 8 byte(s))\n| N # next char specifies size of unsigned value (1, 2, 4, or 8 byte(s))\n| o # octal value (4 bytes)\n| p # pointer reference (2, 4, or 8 bytes)\n| q # quadword (8 bytes)\n| Q # octoword (uint128_t) (16 bytes)\n| r # CPU register (`pf r (eax)plop`)\n| s # 32 bit pointer to string (4 bytes)\n| s # 32 bit pointer to string (4 bytes)\n| t # 32 bit UNIX timestamp (4 bytes)\n| T # show ten first bytes of buffer\n| u # uleb128 (variable length)\n| w # word (2 bytes unsigned short in hex)\n| x # 0xHEX value and flag (fd @ addr) (see 'd' and 'i' formats)\n| X # show formatted hexpairs\n| z # null terminated string\n| Z # null terminated wide string\n| ? # data structure `pf ? (struct_name)example_name`\n| * # next char is pointer (honors 'asm.bits')\n| + # toggle show flags for each offset\n| : # skip 4 bytes\n| . # skip 1 byte\n| ; # rewind 4 bytes\n| , # rewind 1 byte\nUse triple-question-mark pf??? to get some examples using print format strings.\n[0x00001100]> pf???\nUsage: p[=68abcdDfiImrstuxz] [arg|len] [@addr] \n| p[b|B|xb] [len] ([S]) bindump N bits skipping S bytes\n| p[iI][df] [len] print N ops/bytes (f=func) (see pi? and pdq)\n| p[kK] [len] print key in randomart (K is for mosaic)\n| p-[?][jh] [mode] bar|json|histogram blocks (mode: e?search.in)\n| p2 [len] 8x8 2bpp-tiles\n| p6[de] [len] base64 decode/encode\n| p8[?][j] [len] 8bit hexpair list of bytes\n| p=[?][bep] [N] [L] [b] show entropy/printable chars/chars bars\n| pa[edD] [arg] pa:assemble pa[dD]:disasm or pae: esil from hex\n| pb[?] [n] bitstream of N bits\n| pB[?] [n] bitstream of N bytes\n| pc[?][p] [len] output C (or python) format\n| pC[aAcdDxw] [rows] print disassembly in columns (see hex.cols and pdq)\n| pd[?] [sz] [a] [b] disassemble N opcodes (pd) or N bytes (pD)\n| pf[?][.nam] [fmt] print formatted data (pf.name, pf.name $<expr>)\n| pF[?][apx] print asn1, pkcs7 or x509\n| pg[?][x y w h] [cmd] create new visual gadget or print it (see pg? for details)\n| ph[?][=|hash] ([len]) calculate hash for a block\n| pi[?][bdefrj] [num] print instructions\n| pI[?][iI][df] [len] print N instructions/bytes (f=func)\n| pj[?] [len] print as indented JSON\n| pm[?] [magic] print libmagic data (see pm? and /m?)\n| po[?] hex print operation applied to block (see po?)\n| pp[?][sz] [len] print patterns, see pp? for more help\n| pr[?][glx] [len] print N raw bytes (in lines or hexblocks, 'g'unzip)\n| ps[?][pwz] [len] print pascal/wide/zero-terminated strings\n| pt[?][dn] [len] print different timestamps\n| pu[?][w] [len] print N url encoded bytes (w=wide)\n| pv[?][jh] [mode] show variable/pointer/value in memory\n| px[?][owq] [len] hexdump of N bytes (o=octal, w=32bit, q=64bit)\n| plf print the RzIL output of the function\nSome examples are below:\n[0x00001100]> pf i\n0x00001100 = -98693133\n\n[0x00001100]> pf f\n0x00001100 = -2.05176598e+35\n\n\n\n22.0.4 High-level Languages Views\nValid print code formats for human-readable languages are:\n0x00001100]> pc?\nUsage: pc[?] # Print bytes as code byte arrays.\n| pc [<len>] # Generate a C/C++ byte array.\n| pch # Generate a C/C++ 16 bits array.\n| pcw # Generate a C/C++ 32 bits array.\n| pcd # Generate a C/C++ 64 bits array.\n| pca [<len>] # Generate a byte array in GAS assembly.\n| pcA [<len>] # Generate a byte array in GAS assembly with instructions in comments.\n| pcb [<len>] # Generate a bash script with the byte array.\n| pcg [<len>] # Generate a Golang byte array.\n| pcJ [<len>] # Generate a Java byte array.\n| pcj [<len>] # Generate a JSON byte array.\n| pck [<len>] # Generate a Kotlin byte array.\n| pcn [<len>] # Generate a NodeJS buffer.\n| pco [<len>] # Generate a Objective-C/C++ byte array.\n| pcp [<len>] # Generate a Python byte array.\n| pcr [<len>] # Generate a Rust byte array.\n| pcs [<len>] # Generate a Swift byte array.\n| pcy [<len>] # Generate a Yara match pattern.\n| pc* [<len>] # Generate a rizin commands for writing the byte array.\nIf we need to create a .c file containing a binary blob, use the pc command, that creates this output. The default size is like in many other commands: the block size, which can be changed with the b command.\nWe can also just temporarily override this block size by expressing it as an argument.\n[0x00001100]> pc 32\n#define ARRAY_SIZE 32\nconst uint8_t array[ARRAY_SIZE] = {\n 0xf3, 0x0f, 0x1e, 0xfa, 0x31, 0xed, 0x49, 0x89, 0xd1, 0x5e, 0x48, 0x89, 0xe2, 0x48, 0x83, 0xe4,\n 0xf0, 0x50, 0x54, 0x45, 0x31, 0xc0, 0x31, 0xc9, 0x48, 0x8d, 0x3d, 0xca, 0x00, 0x00, 0x00, 0xff\n};\n\n\n22.0.5 Strings\nStrings are probably one of the most important entry points when starting to reverse engineer a program because they usually reference information about functions’ actions (asserts, debug or info messages…). Therefore, Rizin supports various string formats:\n[0x00001100]> ps?\nUsage: ps[?] # Print string at the current offset\n| ps[j] <delimiter>=null # Print the autodetected string at the current offset (null->zero-terminated, block->block-terminated)\n| ps+[j] # Print libc++ std::string (same-endian, ascii, zero-terminated)\n| psb[q] # Print all the strings in current block\n| psc[?] # Generate a C/C++ string\n| psi[?] # Print the first string in the current block\n| psp[j] <bits>=8 # Print the pascal string at the current offset\n| pss[?] # Print string at the current offset in screen (wrap width)\n| psm[j] # Print buffer as a utf16be string\n| psM[j] # Print buffer as a utf32be string\n| psn[j] # Print string with escaped new lines\n| psw[j] # Print buffer as a utf16le string\n| psW[j] # Print buffer as a utf32le string\nMost strings are zero-terminated. Below there is an example using the debugger to continue the execution of a program until it executes the ‘open’ syscall. When we recover the control over the process, we get the arguments passed to the syscall, pointed by %ebx. In the case of the ‘open’ call, it is a zero terminated string which we can inspect using psz.\n[0x4A13B8C0]> dcs open\n0x4a14fc24 syscall(5) open ( 0x4a151c91 0x00000000 0x00000000 ) = 0xffffffda\n[0x4A13B8C0]> dr\n eax 0xffffffda esi 0xffffffff eip 0x4a14fc24\n ebx 0x4a151c91 edi 0x4a151be1 oeax 0x00000005\n ecx 0x00000000 esp 0xbfbedb1c eflags 0x200246\n edx 0x00000000 ebp 0xbfbedbb0 cPaZstIdor0 (PZI)\n[0x4A13B8C0]>\n[0x4A13B8C0]> psz @ 0x4a151c91\n/etc/ld.so.cache\n\n\n22.0.6 Print Memory Contents\nIt is also possible to print various packed data types using the pf command:\n[0xB7F08810]> pf xxS @ rsp\n0x7fff0d29da30 = 0x00000001\n0x7fff0d29da34 = 0x00000000\n0x7fff0d29da38 = 0x7fff0d29da38 -> 0x0d29f7ee /bin/ls\nThis can be used to look at the arguments passed to a function. To achieve this, simply pass a ‘format memory string’ as an argument to pf, and temporally change the current seek position/offset using @. It is also possible to define arrays of structures with pf. To do this, prefix the format string with a numeric value. You can also define a name for each field of the structure by appending them as a space-separated arguments list.\n[0x4A13B8C0]> pf 2*xw pointer type @ esp\n0x00404888 [0] {\n pointer :\n(*0xffffffff8949ed31) type : 0x00404888 = 0x8949ed31\n 0x00404890 = 0x48e2\n}\n0x00404892 [1] {\n(*0x50f0e483) pointer : 0x00404892 = 0x50f0e483\n type : 0x0040489a = 0x2440\n}\nA practical example for using pf on a binary of a GStreamer plugin:\n$ rizin /usr/lib/gstreamer-1.0/libgsttcp.so\n -- Move the comments to the right changing their margin with asm.cmt.margin\n[0x00005020]> aa; pdf @ sym.gst_plugin_tcp_get_desc\n[x] Analyze all flags starting with sym. and entry0 (aa)\n┌ 8: sym.gst_plugin_tcp_get_desc ();\n│ bp: 0 (vars 0, args 0)\n│ sp: 0 (vars 0, args 0)\n│ rg: 0 (vars 0, args 0)\n│ 0x000127f0 lea rax, section..data.rel.ro ; 0x1d460\n└ 0x000127f7 ret\n[0x00005020]> s section..data.rel.ro\n[0x0001d460]> pf ii*z*zp*z*z*z*z*z*z major minor name desc init version license source package origin release_datetime\n major : 0x0001d460 = 1\n minor : 0x0001d464 = 18\n name : (*0x15c8e)0x0001d468 = \"tcp\"\n desc : (*0x17c88)0x0001d470 = \"transfer data over the network via TCP\"\n init : 0x0001d478 = (qword)0x0000000000011430\n version : (*0x15d0b)0x0001d480 = \"1.18.2\"\n license : (*0x15d3e)0x0001d488 = \"LGPL\"\n source : (*0x15d2d)0x0001d490 = \"gst-plugins-base\"\n package : (*0x17cb0)0x0001d498 = \"GStreamer Base Plugins (Arch Linux)\"\n origin : (*0x15d12)0x0001d4a0 = \"https://www.archlinux.org/\"\n release_datetime : (*0x15d43)0x0001d4a8 = \"2020-12-06\"\n\n\n22.0.7 Disassembly\nThe pd command is used to disassemble code. It accepts a numeric value to specify how many instructions should be disassembled. The pD command is similar but instead of a number of instructions, it decompiles a given number of bytes.\n\npd : Disassemble N instructions (can be negative)\npD : Disassemble N bytes (can be negative)\n\n[0x00001100]> pd 1\n ;-- entry0:\n ;-- section..text:\n ;-- _start:\n 0x00001100 endbr64 ; [14] -r-x section size 409 named .text\n\n\n22.0.8 Selecting Target Architecture\nThe architecture flavor for the disassembler is defined by the asm.arch eval variable. You can use e asm.arch=?? to list all available architectures.\n[0x00001100]> e asm.arch=??\n_dAeI 8 16 6502 LGPL3 6502/NES/C64/Tamagotchi/T-1000 CPU\nadAeI 8 8051 PD 8051 Intel CPU\n_dA__ 32 amd29k LGPL3 AMD 29k RISC CPU (by deroad)\n_dA__ 16 32 arc GPL3 Argonaut RISC Core\nadAeI 16 32 64 arm BSD Capstone ARM disassembler\na____ 16 32 64 arm.as LGPL3 as ARM Assembler (use RZ_ARM32_AS and RZ_ARM64_AS environment) (by pancake)\nadAeI 8 16 avr LGPL3 AVR Atmel\nadA_I 16 32 64 bf LGPL3 Brainfuck (by pancake, nibble) v4.0.0\n_dA__ 32 chip8 LGPL3 Chip8 disassembler\n_dA__ 16 32 64 cil LGPL3 .NET Common Intermediate Language\n_dA__ 16 cr16 LGPL3 cr16 disassembly plugin\n_dA__ 32 cris GPL3 Axis Communications 32-bit embedded processor (by pancake)\nadA__ 32 64 dalvik LGPL3 AndroidVM Dalvik\nad___ 16 dcpu16 PD Mojang's DCPU-16\n_dA__ 32 64 ebc LGPL3 EFI Bytecode (by Fedor Sakharov)\nadAeI 16 gb LGPL3 GameBoy(TM) (z80-like) (by condret)\n_dAe_ 16 h8300 LGPL3 H8/300 disassembly plugin\n_dA_I 32 hexagon LGPL3 Qualcomm Hexagon (QDSP6) V6 (by Rot127)\n_d___ 32 hppa GPL3 HP PA-RISC\n_dA__ 4 i4004 LGPL3 Intel 4004 microprocessor\n_dA__ 8 i8080 BSD Intel 8080 CPU\nadA__ 32 java LGPL-3 Java bytecode disassembler (by deroad)\n_d___ 32 lanai GPL3 LANAI\n...\n\n\n22.0.9 Configuring the Disassembler\nThere are multiple options which can be used to configure the output of the disassembler. All these options are described in el asm.\n[0x00001100]> el asm.\n asm.analysis: Analyze code and refs while disassembling (see analysis.strings)\n asm.arch: Set the arch to be used by asm\n asm.assembler: Set the plugin name to use when assembling\n asm.bb.line: Show empty line after every basic block\n asm.bb.middle: Realign disassembly if a basic block starts in the middle of an instruction\n asm.bits: Word size in bits at assembler\n asm.bytes: Display the bytes of each instruction\n asm.bytes.right: Display the bytes at the right of the disassembly\n asm.bytes.space: Separate hexadecimal bytes with a whitespace\n asm.calls: Show callee function related info as comments in disasm\n asm.capitalize: Use camelcase at disassembly\n asm.cmt.col: Column to align comments\n asm.cmt.esil: Show ESIL expressions as comments\n asm.cmt.flgrefs: Show comment flags associated to branch reference\n...\nCurrently, there are 130 asm. configuration variables so we do not list them all.\n\n\n22.0.10 Disassembly Syntax\nThe asm.syntax variable is used to change the flavor of the assembly syntax used by a disassembler engine. To switch between Intel and AT&T representations:\ne asm.syntax=intel\ne asm.syntax=att\nYou can also check asm.pseudo, which is an experimental pseudocode view, and asm.esil which outputs ESIL (‘Evaluable Strings Intermediate Language’). ESIL’s goal is to have a human-readable representation of every opcode semantics. Such representations can be evaluated (interpreted) to emulate effects of individual instructions.\n\n\n22.0.11 Print gadgets\nIn Rizin, visual gadgets allows the users to cast or display the output of a particular Rizin command anywhere on the screen while in Visual mode. This command is unrelated with displaying ROP Gadgets.\nUsing the commands under pg (print gadgets), we can add, remove and change the location of these visual gadgets. You can add a gadget using pg:\npg 10 10 10 10 ddr\nThis will add the output of the Rizin command ddr be printed on the screen. The four arguments to be passed are the position (like coordinates) and the height and width of the gadget you would like to see. This command requires the configuration variable scr.gadgets to be turned on.\nSee pg? for more information.", + "text": "One of the key features of Rizin is displaying information in many formats. The goal is to offer a selection of display choices to interpret binary data in the best possible way.\nBinary data can be represented as integers, shorts, longs, floats, timestamps, hexpair strings, or more complex formats like C structures, disassembly listings, decompilation listing, be a result of an external processing…\nBelow is a list of available print modes listed by p?:\n[0x00001100]> p?\nUsage: p[=68abcdDfiImrstuxz] [arg|len] [@addr] \n| p[b|B|xb] [len] ([S]) bindump N bits skipping S bytes\n| p[iI][df] [len] print N ops/bytes (f=func) (see pi? and pdq)\n| p[kK] [len] print key in randomart (K is for mosaic)\n| p-[?][jh] [mode] bar|json|histogram blocks (mode: e?search.in)\n| p2 [len] 8x8 2bpp-tiles\n| p6[de] [len] base64 decode/encode\n| p8[?][j] [len] 8bit hexpair list of bytes\n| p=[?][bep] [N] [L] [b] show entropy/printable chars/chars bars\n| pa[edD] [arg] pa:assemble pa[dD]:disasm or pae: esil from hex\n| pb[?] [n] bitstream of N bits\n| pB[?] [n] bitstream of N bytes\n| pc[?][p] [len] output C (or python) format\n| pC[aAcdDxw] [rows] print disassembly in columns (see hex.cols and pdq)\n| pd[?] [sz] [a] [b] disassemble N opcodes (pd) or N bytes (pD)\n| pf[?][.nam] [fmt] print formatted data (pf.name, pf.name $<expr>)\n| pF[?][apx] print asn1, pkcs7 or x509\n| pg[?][x y w h] [cmd] create new visual gadget or print it (see pg? for details)\n| ph[?][=|hash] ([len]) calculate hash for a block\n| pi[?][bdefrj] [num] print instructions\n| pI[?][iI][df] [len] print N instructions/bytes (f=func)\n| pj[?] [len] print as indented JSON\n| pm[?] [magic] print libmagic data (see pm? and /m?)\n| po[?] hex print operation applied to block (see po?)\n| pp[?][sz] [len] print patterns, see pp? for more help\n| pr[?][glx] [len] print N raw bytes (in lines or hexblocks, 'g'unzip)\n| ps[?][pwz] [len] print pascal/wide/zero-terminated strings\n| pt[?][dn] [len] print different timestamps\n| pu[?][w] [len] print N url encoded bytes (w=wide)\n| pv[?][jh] [mode] show variable/pointer/value in memory\n| px[?][owq] [len] hexdump of N bytes (o=octal, w=32bit, q=64bit)\n| plf print the RzIL output of the function\nTip: when using json output, you can append the ~{} to the command to get a pretty-printed version of the output:\n[0x00000000]> olj\n[{\"raised\":false,\"fd\":563280,\"uri\":\"malloc://512\",\"from\":0,\"writable\":true,\"size\":512,\"overlaps\":false}]\n[0x00000000]> olj~{}\n[\n {\n \"raised\": false,\n \"fd\": 563280,\n \"uri\": \"malloc://512\",\n \"from\": 0,\n \"writable\": true,\n \"size\": 512,\n \"overlaps\": false\n }\n]\nFor more on the magical powers of ~ see the help in ?@?, and the Rizin Command-line chapter earlier in the book.\n\n23.0.1 Hexadecimal View\npx gives a user-friendly output showing 16 pairs of numbers per row with offsets and raw representations:\n[0x00001100]> px\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\n0x00001100 f30f 1efa 31ed 4989 d15e 4889 e248 83e4 ....1.I..^H..H..\n0x00001110 f050 5445 31c0 31c9 488d 3dca 0000 00ff .PTE1.1.H.=.....\n0x00001120 15b3 2e00 00f4 662e 0f1f 8400 0000 0000 ......f.........\n\n23.0.1.1 Show Hexadecimal Words Dump (32 bits)\n[0x00001100]> pxw\n0x00001100 0xfa1e0ff3 0x8949ed31 0x89485ed1 0xe48348e2 ....1.I..^H..H..\n0x00001110 0x455450f0 0xc931c031 0xca3d8d48 0xff000000 .PTE1.1.H.=.....\n0x00001120 0x002eb315 0x2e66f400 0x00841f0f 0x00000000 ......f.........\n\n[0x00001100]> e cfg.bigendian\nfalse\n\n[0x00001100]> e cfg.bigendian=true\n\n[0x00001100]> pxw\n0x00001100 0xf30f1efa 0x31ed4989 0xd15e4889 0xe24883e4 ....1.I..^H..H..\n0x00001110 0xf0505445 0x31c031c9 0x488d3dca 0x000000ff .PTE1.1.H.=.....\n0x00001120 0x15b32e00 0x00f4662e 0x0f1f8400 0x00000000 ......f.........\n\n[0x00001100]> e cfg.bigendian=false\n\n\n23.0.1.2 8 bits Hexpair List of Bytes\n[0x00001100]> p8 16\nf30f1efa31ed4989d15e4889e24883e4\n\n\n23.0.1.3 Show Hexadecimal Quad-words Dump (64 bits)\n[0x00001100]> pxq\n0x00001100 0x8949ed31fa1e0ff3 0xe48348e289485ed1 ....1.I..^H..H..\n0x00001110 0xc931c031455450f0 0xff000000ca3d8d48 .PTE1.1.H.=.....\n0x00001120 0x2e66f400002eb315 0x0000000000841f0f ......f.........\n0x00001130 0x4800002ed93d8d48 0x394800002ed2058d H.=....H......H9\n\n\n\n23.0.2 Date/Time Formats\nCurrently supported timestamp output modes are:\n[0x00404888]> pt?\nUsage: pt[.dhn] # Print timestamps\n| pt # Print UNIX epoch time (32 bit `cfg.bigendian`, since January 1, 1970)\n| pt. # Print the current time\n| ptd # Print MS-DOS time (32 bit `cfg.bigendian`, since January 1, 1980)\n| pth # Print Mac HFS time (32 bit `cfg.bigendian`, since January 1, 1904)\n| ptn # Print NTFS time (64 bit `cfg.bigendian`, since January 1, 1601)\nFor example, you can ‘view’ the current buffer as timestamps in the ntfs time:\n[0x08048000]> e cfg.bigendian=false\n[0x08048000]> pt 4\n29:04:32948 23:12:36 +0000\n[0x08048000]> e cfg.bigendian=true\n[0x08048000]> pt 4\n20:05:13001 09:29:21 +0000\nAs you can see, the endianness affects the result. Once you have printed a timestamp, you can grep the output, for example, by year:\n[0x08048000]> pt ~1974 | wc -l\n15\n[0x08048000]> pt ~2022\n27:04:2022 16:15:43 +0000\nThe default date format can be configured using the cfg.datefmt variable. Formatting rules for it follow the well known strftime(3) format. Check the manpage for more details, but these are the most important:\n%a The abbreviated name of the day of the week according to the current locale.\n%A The full name of the day of the week according to the current locale.\n%d The day of the month as a decimal number (range 01 to 31).\n%D Equivalent to %m/%d/%y. (Yecch—for Americans only).\n%H The hour as a decimal number using a 24-hour clock (range 00 to 23).\n%I The hour as a decimal number using a 12-hour clock (range 01 to 12).\n%m The month as a decimal number (range 01 to 12).\n%M The minute as a decimal number (range 00 to 59).\n%p Either \"AM\" or \"PM\" according to the given time value.\n%s The number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). (TZ)\n%S The second as a decimal number (range 00 to 60). (The range is up to 60 to allow for occasional leap seconds.)\n%T The time in 24-hour notation (%H:%M:%S). (SU)\n%y The year as a decimal number without a century (range 00 to 99).\n%Y The year as a decimal number including the century.\n%z The +hhmm or -hhmm numeric timezone (that is, the hour and minute offset from UTC). (SU)\n%Z The timezone name or abbreviation.\n\n\n23.0.3 Basic Types\nThere are print modes available for all basic types. If you are interested in a more complex structure, type pf?? for format characters and pf??? for examples:\n[0x00499999]> pf??\nUsage: pf[j*q] <format> # Show data using given format string\n| pf <format> # Show data using given format string\n| pfj <format> # Show data using given format string (JSON mode)\n| pf* <format> # Show data using given format string (rizin mode)\n| pfq <format> # Show data using given format string (quiet mode)\n\nFormats:\n| b # byte (unsigned)\n| B # resolve enum bitfield (see t?)\n| c # char (signed byte)\n| C # byte in decimal\n| d # 0xHEX value (4 bytes) (see 'i' and 'x' formats)\n| D # disassemble one opcode\n| e # temporarily swap endian\n| E # resolve enum name (see t?)\n| f # float value (4 bytes)\n| F # double float value (8 bytes)\n| i # signed integer value (4 bytes) (see 'd' and 'x' formats)\n| n # next char specifies size of signed value (1, 2, 4, or 8 byte(s))\n| N # next char specifies size of unsigned value (1, 2, 4, or 8 byte(s))\n| o # octal value (4 bytes)\n| p # pointer reference (2, 4, or 8 bytes)\n| q # quadword (8 bytes)\n| Q # octoword (uint128_t) (16 bytes)\n| r # CPU register (`pf r (eax)plop`)\n| s # 32 bit pointer to string (4 bytes)\n| s # 32 bit pointer to string (4 bytes)\n| t # 32 bit UNIX timestamp (4 bytes)\n| T # show ten first bytes of buffer\n| u # uleb128 (variable length)\n| w # word (2 bytes unsigned short in hex)\n| x # 0xHEX value and flag (fd @ addr) (see 'd' and 'i' formats)\n| X # show formatted hexpairs\n| z # null terminated string\n| Z # null terminated wide string\n| ? # data structure `pf ? (struct_name)example_name`\n| * # next char is pointer (honors 'asm.bits')\n| + # toggle show flags for each offset\n| : # skip 4 bytes\n| . # skip 1 byte\n| ; # rewind 4 bytes\n| , # rewind 1 byte\nUse triple-question-mark pf??? to get some examples using print format strings.\n[0x00001100]> pf???\nUsage: p[=68abcdDfiImrstuxz] [arg|len] [@addr] \n| p[b|B|xb] [len] ([S]) bindump N bits skipping S bytes\n| p[iI][df] [len] print N ops/bytes (f=func) (see pi? and pdq)\n| p[kK] [len] print key in randomart (K is for mosaic)\n| p-[?][jh] [mode] bar|json|histogram blocks (mode: e?search.in)\n| p2 [len] 8x8 2bpp-tiles\n| p6[de] [len] base64 decode/encode\n| p8[?][j] [len] 8bit hexpair list of bytes\n| p=[?][bep] [N] [L] [b] show entropy/printable chars/chars bars\n| pa[edD] [arg] pa:assemble pa[dD]:disasm or pae: esil from hex\n| pb[?] [n] bitstream of N bits\n| pB[?] [n] bitstream of N bytes\n| pc[?][p] [len] output C (or python) format\n| pC[aAcdDxw] [rows] print disassembly in columns (see hex.cols and pdq)\n| pd[?] [sz] [a] [b] disassemble N opcodes (pd) or N bytes (pD)\n| pf[?][.nam] [fmt] print formatted data (pf.name, pf.name $<expr>)\n| pF[?][apx] print asn1, pkcs7 or x509\n| pg[?][x y w h] [cmd] create new visual gadget or print it (see pg? for details)\n| ph[?][=|hash] ([len]) calculate hash for a block\n| pi[?][bdefrj] [num] print instructions\n| pI[?][iI][df] [len] print N instructions/bytes (f=func)\n| pj[?] [len] print as indented JSON\n| pm[?] [magic] print libmagic data (see pm? and /m?)\n| po[?] hex print operation applied to block (see po?)\n| pp[?][sz] [len] print patterns, see pp? for more help\n| pr[?][glx] [len] print N raw bytes (in lines or hexblocks, 'g'unzip)\n| ps[?][pwz] [len] print pascal/wide/zero-terminated strings\n| pt[?][dn] [len] print different timestamps\n| pu[?][w] [len] print N url encoded bytes (w=wide)\n| pv[?][jh] [mode] show variable/pointer/value in memory\n| px[?][owq] [len] hexdump of N bytes (o=octal, w=32bit, q=64bit)\n| plf print the RzIL output of the function\nSome examples are below:\n[0x00001100]> pf i\n0x00001100 = -98693133\n\n[0x00001100]> pf f\n0x00001100 = -2.05176598e+35\n\n\n\n23.0.4 High-level Languages Views\nValid print code formats for human-readable languages are:\n0x00001100]> pc?\nUsage: pc[?] # Print bytes as code byte arrays.\n| pc [<len>] # Generate a C/C++ byte array.\n| pch # Generate a C/C++ 16 bits array.\n| pcw # Generate a C/C++ 32 bits array.\n| pcd # Generate a C/C++ 64 bits array.\n| pca [<len>] # Generate a byte array in GAS assembly.\n| pcA [<len>] # Generate a byte array in GAS assembly with instructions in comments.\n| pcb [<len>] # Generate a bash script with the byte array.\n| pcg [<len>] # Generate a Golang byte array.\n| pcJ [<len>] # Generate a Java byte array.\n| pcj [<len>] # Generate a JSON byte array.\n| pck [<len>] # Generate a Kotlin byte array.\n| pcn [<len>] # Generate a NodeJS buffer.\n| pco [<len>] # Generate a Objective-C/C++ byte array.\n| pcp [<len>] # Generate a Python byte array.\n| pcr [<len>] # Generate a Rust byte array.\n| pcs [<len>] # Generate a Swift byte array.\n| pcy [<len>] # Generate a Yara match pattern.\n| pc* [<len>] # Generate a rizin commands for writing the byte array.\nIf we need to create a .c file containing a binary blob, use the pc command, that creates this output. The default size is like in many other commands: the block size, which can be changed with the b command.\nWe can also just temporarily override this block size by expressing it as an argument.\n[0x00001100]> pc 32\n#define ARRAY_SIZE 32\nconst uint8_t array[ARRAY_SIZE] = {\n 0xf3, 0x0f, 0x1e, 0xfa, 0x31, 0xed, 0x49, 0x89, 0xd1, 0x5e, 0x48, 0x89, 0xe2, 0x48, 0x83, 0xe4,\n 0xf0, 0x50, 0x54, 0x45, 0x31, 0xc0, 0x31, 0xc9, 0x48, 0x8d, 0x3d, 0xca, 0x00, 0x00, 0x00, 0xff\n};\n\n\n23.0.5 Strings\nStrings are probably one of the most important entry points when starting to reverse engineer a program because they usually reference information about functions’ actions (asserts, debug or info messages…). Therefore, Rizin supports various string formats:\n[0x00001100]> ps?\nUsage: ps[?] # Print string at the current offset\n| ps[j] <delimiter>=null # Print the autodetected string at the current offset (null->zero-terminated, block->block-terminated)\n| ps+[j] # Print libc++ std::string (same-endian, ascii, zero-terminated)\n| psb[q] # Print all the strings in current block\n| psc[?] # Generate a C/C++ string\n| psi[?] # Print the first string in the current block\n| psp[j] <bits>=8 # Print the pascal string at the current offset\n| pss[?] # Print string at the current offset in screen (wrap width)\n| psm[j] # Print buffer as a utf16be string\n| psM[j] # Print buffer as a utf32be string\n| psn[j] # Print string with escaped new lines\n| psw[j] # Print buffer as a utf16le string\n| psW[j] # Print buffer as a utf32le string\nMost strings are zero-terminated. Below there is an example using the debugger to continue the execution of a program until it executes the ‘open’ syscall. When we recover the control over the process, we get the arguments passed to the syscall, pointed by %ebx. In the case of the ‘open’ call, it is a zero terminated string which we can inspect using psz.\n[0x4A13B8C0]> dcs open\n0x4a14fc24 syscall(5) open ( 0x4a151c91 0x00000000 0x00000000 ) = 0xffffffda\n[0x4A13B8C0]> dr\n eax 0xffffffda esi 0xffffffff eip 0x4a14fc24\n ebx 0x4a151c91 edi 0x4a151be1 oeax 0x00000005\n ecx 0x00000000 esp 0xbfbedb1c eflags 0x200246\n edx 0x00000000 ebp 0xbfbedbb0 cPaZstIdor0 (PZI)\n[0x4A13B8C0]>\n[0x4A13B8C0]> psz @ 0x4a151c91\n/etc/ld.so.cache\n\n\n23.0.6 Print Memory Contents\nIt is also possible to print various packed data types using the pf command:\n[0xB7F08810]> pf xxS @ rsp\n0x7fff0d29da30 = 0x00000001\n0x7fff0d29da34 = 0x00000000\n0x7fff0d29da38 = 0x7fff0d29da38 -> 0x0d29f7ee /bin/ls\nThis can be used to look at the arguments passed to a function. To achieve this, simply pass a ‘format memory string’ as an argument to pf, and temporally change the current seek position/offset using @. It is also possible to define arrays of structures with pf. To do this, prefix the format string with a numeric value. You can also define a name for each field of the structure by appending them as a space-separated arguments list.\n[0x4A13B8C0]> pf 2*xw pointer type @ esp\n0x00404888 [0] {\n pointer :\n(*0xffffffff8949ed31) type : 0x00404888 = 0x8949ed31\n 0x00404890 = 0x48e2\n}\n0x00404892 [1] {\n(*0x50f0e483) pointer : 0x00404892 = 0x50f0e483\n type : 0x0040489a = 0x2440\n}\nA practical example for using pf on a binary of a GStreamer plugin:\n$ rizin /usr/lib/gstreamer-1.0/libgsttcp.so\n -- Move the comments to the right changing their margin with asm.cmt.margin\n[0x00005020]> aa; pdf @ sym.gst_plugin_tcp_get_desc\n[x] Analyze all flags starting with sym. and entry0 (aa)\n┌ 8: sym.gst_plugin_tcp_get_desc ();\n│ bp: 0 (vars 0, args 0)\n│ sp: 0 (vars 0, args 0)\n│ rg: 0 (vars 0, args 0)\n│ 0x000127f0 lea rax, section..data.rel.ro ; 0x1d460\n└ 0x000127f7 ret\n[0x00005020]> s section..data.rel.ro\n[0x0001d460]> pf ii*z*zp*z*z*z*z*z*z major minor name desc init version license source package origin release_datetime\n major : 0x0001d460 = 1\n minor : 0x0001d464 = 18\n name : (*0x15c8e)0x0001d468 = \"tcp\"\n desc : (*0x17c88)0x0001d470 = \"transfer data over the network via TCP\"\n init : 0x0001d478 = (qword)0x0000000000011430\n version : (*0x15d0b)0x0001d480 = \"1.18.2\"\n license : (*0x15d3e)0x0001d488 = \"LGPL\"\n source : (*0x15d2d)0x0001d490 = \"gst-plugins-base\"\n package : (*0x17cb0)0x0001d498 = \"GStreamer Base Plugins (Arch Linux)\"\n origin : (*0x15d12)0x0001d4a0 = \"https://www.archlinux.org/\"\n release_datetime : (*0x15d43)0x0001d4a8 = \"2020-12-06\"\n\n\n23.0.7 Disassembly\nThe pd command is used to disassemble code. It accepts a numeric value to specify how many instructions should be disassembled. The pD command is similar but instead of a number of instructions, it decompiles a given number of bytes.\n\npd : Disassemble N instructions (can be negative)\npD : Disassemble N bytes (can be negative)\n\n[0x00001100]> pd 1\n ;-- entry0:\n ;-- section..text:\n ;-- _start:\n 0x00001100 endbr64 ; [14] -r-x section size 409 named .text\n\n\n23.0.8 Selecting Target Architecture\nThe architecture flavor for the disassembler is defined by the asm.arch eval variable. You can use e asm.arch=?? to list all available architectures.\n[0x00001100]> e asm.arch=??\n_dAeI 8 16 6502 LGPL3 6502/NES/C64/Tamagotchi/T-1000 CPU\nadAeI 8 8051 PD 8051 Intel CPU\n_dA__ 32 amd29k LGPL3 AMD 29k RISC CPU (by deroad)\n_dA__ 16 32 arc GPL3 Argonaut RISC Core\nadAeI 16 32 64 arm BSD Capstone ARM disassembler\na____ 16 32 64 arm.as LGPL3 as ARM Assembler (use RZ_ARM32_AS and RZ_ARM64_AS environment) (by pancake)\nadAeI 8 16 avr LGPL3 AVR Atmel\nadA_I 16 32 64 bf LGPL3 Brainfuck (by pancake, nibble) v4.0.0\n_dA__ 32 chip8 LGPL3 Chip8 disassembler\n_dA__ 16 32 64 cil LGPL3 .NET Common Intermediate Language\n_dA__ 16 cr16 LGPL3 cr16 disassembly plugin\n_dA__ 32 cris GPL3 Axis Communications 32-bit embedded processor (by pancake)\nadA__ 32 64 dalvik LGPL3 AndroidVM Dalvik\nad___ 16 dcpu16 PD Mojang's DCPU-16\n_dA__ 32 64 ebc LGPL3 EFI Bytecode (by Fedor Sakharov)\nadAeI 16 gb LGPL3 GameBoy(TM) (z80-like) (by condret)\n_dAe_ 16 h8300 LGPL3 H8/300 disassembly plugin\n_dA_I 32 hexagon LGPL3 Qualcomm Hexagon (QDSP6) V6 (by Rot127)\n_d___ 32 hppa GPL3 HP PA-RISC\n_dA__ 4 i4004 LGPL3 Intel 4004 microprocessor\n_dA__ 8 i8080 BSD Intel 8080 CPU\nadA__ 32 java LGPL-3 Java bytecode disassembler (by deroad)\n_d___ 32 lanai GPL3 LANAI\n...\n\n\n23.0.9 Configuring the Disassembler\nThere are multiple options which can be used to configure the output of the disassembler. All these options are described in el asm.\n[0x00001100]> el asm.\n asm.analysis: Analyze code and refs while disassembling (see analysis.strings)\n asm.arch: Set the arch to be used by asm\n asm.assembler: Set the plugin name to use when assembling\n asm.bb.line: Show empty line after every basic block\n asm.bb.middle: Realign disassembly if a basic block starts in the middle of an instruction\n asm.bits: Word size in bits at assembler\n asm.bytes: Display the bytes of each instruction\n asm.bytes.right: Display the bytes at the right of the disassembly\n asm.bytes.space: Separate hexadecimal bytes with a whitespace\n asm.calls: Show callee function related info as comments in disasm\n asm.capitalize: Use camelcase at disassembly\n asm.cmt.col: Column to align comments\n asm.cmt.esil: Show ESIL expressions as comments\n asm.cmt.flgrefs: Show comment flags associated to branch reference\n...\nCurrently, there are 130 asm. configuration variables so we do not list them all.\n\n\n23.0.10 Disassembly Syntax\nThe asm.syntax variable is used to change the flavor of the assembly syntax used by a disassembler engine. To switch between Intel and AT&T representations:\ne asm.syntax=intel\ne asm.syntax=att\nYou can also check asm.pseudo, which is an experimental pseudocode view, and asm.esil which outputs ESIL (‘Evaluable Strings Intermediate Language’). ESIL’s goal is to have a human-readable representation of every opcode semantics. Such representations can be evaluated (interpreted) to emulate effects of individual instructions.\n\n\n23.0.11 Print gadgets\nIn Rizin, visual gadgets allows the users to cast or display the output of a particular Rizin command anywhere on the screen while in Visual mode. This command is unrelated with displaying ROP Gadgets.\nUsing the commands under pg (print gadgets), we can add, remove and change the location of these visual gadgets. You can add a gadget using pg:\npg 10 10 10 10 ddr\nThis will add the output of the Rizin command ddr be printed on the screen. The four arguments to be passed are the position (like coordinates) and the height and width of the gadget you would like to see. This command requires the configuration variable scr.gadgets to be turned on.\nSee pg? for more information.", "crumbs": [ "Basic Commands", - "22  Print Modes" + "23  Print Modes" ] }, { "objectID": "src/basic_commands/flags.html", "href": "src/basic_commands/flags.html", - "title": "23  Flags", + "title": "24  Flags", "section": "", - "text": "Flags are conceptually similar to bookmarks. They associate a name with a given offset in a file. Flags can be grouped into ‘flagspaces’. A flagspace is a namespace for flags, grouping together flags of similar characteristics or type. Examples for flagspaces: sections, registers or symbols.\nTo create a flag:\n[0x100003ba0]> f flag_name @ offset\nYou can remove a flag by appending the - character to command. Most commands accept - as argument-prefix as an indication to delete something.\n[0x100003ba0]> f-flag_name\nTo switch between or create new flagspaces use the fs command:\n[0x100003ba0]> fs?\nUsage: fs[l-mrs?] # Manage flagspaces\n| fs <name> # Add the flagspace\n| fsl[jq] # Display flagspaces\n| fs- <name> # Remove the flagspace\n| fs-* # Remove all flagspaces\n| fsm # Move the flags at the current address to the current flagspace\n| fsr <newname> # Rename the flag space\n| fss<+-l> # Manage the flagspace stack\n[0x100003ba0]> fsl\n| 0 * classes\n| 108 * functions\n| 84 * imports\n| 0 * platform.ports\n| 87 * pointers\n| 0 * registers\n| 0 * registers.extended\n| 0 * registers.mmio\n| 91 * relocs\n| 13 * sections\n| 3 * segments\n| 95 * strings\n| 55 * symbols\nHere you can find some command examples using flagspaces:\n[0x100003ba0]> fs symbols ; select only flags in symbols flagspace\n[0x100003ba0]> fsl\n 0 . classes\n 108 . functions\n 84 . imports\n 0 . platform.ports\n 87 . pointers\n 0 . registers\n 0 . registers.extended\n 0 . registers.mmio\n 91 . relocs\n 13 . sections\n 3 . segments\n 95 . strings\n 55 * symbols ; symbols are selected\n[0x100003ba0]> fl ; list only flags in symbols flagspace\n[0x100003ba0]> fs * ; select all flagspaces\n[0x100003ba0]> f myflag ; create a new flag called 'myflag'\n[0x100003ba0]> f-myflag ; delete the flag called 'myflag'\nYou can rename flags with fr.\n\n23.0.1 Local flags\nEvery flag name should be unique for addressing reasons. But it is quite a common need to have the flags, for example inside the functions, with simple and ubiquitous names like loop or return. For this purpose you can use so-called “local” flags, which are tied to the function where they reside. It is possible to add them using f. command:\n[0x00003a04]> pd 10\n│ 0x00003a04 48c705c9cc21. mov qword [0x002206d8], 0xffffffffffffffff ;\n[0x2206d8:8]=0\n│ 0x00003a0f c60522cc2100. mov byte [0x00220638], 0 ; [0x220638:1]=0\n│ 0x00003a16 83f802 cmp eax, 2\n│ .─< 0x00003a19 0f84880d0000 je 0x47a7\n│ │ 0x00003a1f 83f803 cmp eax, 3\n│ .──< 0x00003a22 740e je 0x3a32\n│ ││ 0x00003a24 83e801 sub eax, 1\n│.───< 0x00003a27 0f84ed080000 je 0x431a\n││││ 0x00003a2d e8fef8ffff call sym.imp.abort ; void abort(void)\n││││ ; CODE XREF from main (0x3a22)\n││╰──> 0x00003a32 be07000000 mov esi, 7\n[0x00003a04]> f. localflag @ 0x3a32\n[0x00003a04]> f.\n0x00003a32 localflag [main + 210]\n[0x00003a04]> pd 10\n│ 0x00003a04 48c705c9cc21. mov qword [0x002206d8], 0xffffffffffffffff ;\n[0x2206d8:8]=0\n│ 0x00003a0f c60522cc2100. mov byte [0x00220638], 0 ; [0x220638:1]=0\n│ 0x00003a16 83f802 cmp eax, 2\n│ .─< 0x00003a19 0f84880d0000 je 0x47a7\n│ │ 0x00003a1f 83f803 cmp eax, 3\n│ .──< 0x00003a22 740e je 0x3a32 ; main.localflag\n│ ││ 0x00003a24 83e801 sub eax, 1\n│.───< 0x00003a27 0f84ed080000 je 0x431a\n││││ 0x00003a2d e8fef8ffff call sym.imp.abort ; void abort(void)\n││││ ; CODE XREF from main (0x3a22)\n││`──> .localflag:\n││││ ; CODE XREF from main (0x3a22)\n││`──> 0x00003a32 be07000000 mov esi, 7\n[0x00003a04]>\n\n\n23.0.2 Flag Zones\nRizin offers flag zones, which lets you label different offsets on the scrollbar, for making it easier to navigate through large binaries. You can set a flag zone on the current seek using:\n[0x00003a04]> fz flag-zone-name\nSet e scr.scrollbar=1 and go to the Visual mode, to see your flag zone appear on the scrollbar on the right end of the window.\nSee fz? for more information.", + "text": "Flags are conceptually similar to bookmarks. They associate a name with a given offset in a file. Flags can be grouped into ‘flagspaces’. A flagspace is a namespace for flags, grouping together flags of similar characteristics or type. Examples for flagspaces: sections, registers or symbols.\nTo create a flag:\n[0x100003ba0]> f flag_name @ offset\nYou can remove a flag by appending the - character to command. Most commands accept - as argument-prefix as an indication to delete something.\n[0x100003ba0]> f-flag_name\nTo switch between or create new flagspaces use the fs command:\n[0x100003ba0]> fs?\nUsage: fs[l-mrs?] # Manage flagspaces\n| fs <name> # Add the flagspace\n| fsl[jq] # Display flagspaces\n| fs- <name> # Remove the flagspace\n| fs-* # Remove all flagspaces\n| fsm # Move the flags at the current address to the current flagspace\n| fsr <newname> # Rename the flag space\n| fss<+-l> # Manage the flagspace stack\n[0x100003ba0]> fsl\n| 0 * classes\n| 108 * functions\n| 84 * imports\n| 0 * platform.ports\n| 87 * pointers\n| 0 * registers\n| 0 * registers.extended\n| 0 * registers.mmio\n| 91 * relocs\n| 13 * sections\n| 3 * segments\n| 95 * strings\n| 55 * symbols\nHere you can find some command examples using flagspaces:\n[0x100003ba0]> fs symbols ; select only flags in symbols flagspace\n[0x100003ba0]> fsl\n 0 . classes\n 108 . functions\n 84 . imports\n 0 . platform.ports\n 87 . pointers\n 0 . registers\n 0 . registers.extended\n 0 . registers.mmio\n 91 . relocs\n 13 . sections\n 3 . segments\n 95 . strings\n 55 * symbols ; symbols are selected\n[0x100003ba0]> fl ; list only flags in symbols flagspace\n[0x100003ba0]> fs * ; select all flagspaces\n[0x100003ba0]> f myflag ; create a new flag called 'myflag'\n[0x100003ba0]> f-myflag ; delete the flag called 'myflag'\nYou can rename flags with fr.\n\n24.0.1 Local flags\nEvery flag name should be unique for addressing reasons. But it is quite a common need to have the flags, for example inside the functions, with simple and ubiquitous names like loop or return. For this purpose you can use so-called “local” flags, which are tied to the function where they reside. It is possible to add them using f. command:\n[0x00003a04]> pd 10\n│ 0x00003a04 48c705c9cc21. mov qword [0x002206d8], 0xffffffffffffffff ;\n[0x2206d8:8]=0\n│ 0x00003a0f c60522cc2100. mov byte [0x00220638], 0 ; [0x220638:1]=0\n│ 0x00003a16 83f802 cmp eax, 2\n│ .─< 0x00003a19 0f84880d0000 je 0x47a7\n│ │ 0x00003a1f 83f803 cmp eax, 3\n│ .──< 0x00003a22 740e je 0x3a32\n│ ││ 0x00003a24 83e801 sub eax, 1\n│.───< 0x00003a27 0f84ed080000 je 0x431a\n││││ 0x00003a2d e8fef8ffff call sym.imp.abort ; void abort(void)\n││││ ; CODE XREF from main (0x3a22)\n││╰──> 0x00003a32 be07000000 mov esi, 7\n[0x00003a04]> f. localflag @ 0x3a32\n[0x00003a04]> f.\n0x00003a32 localflag [main + 210]\n[0x00003a04]> pd 10\n│ 0x00003a04 48c705c9cc21. mov qword [0x002206d8], 0xffffffffffffffff ;\n[0x2206d8:8]=0\n│ 0x00003a0f c60522cc2100. mov byte [0x00220638], 0 ; [0x220638:1]=0\n│ 0x00003a16 83f802 cmp eax, 2\n│ .─< 0x00003a19 0f84880d0000 je 0x47a7\n│ │ 0x00003a1f 83f803 cmp eax, 3\n│ .──< 0x00003a22 740e je 0x3a32 ; main.localflag\n│ ││ 0x00003a24 83e801 sub eax, 1\n│.───< 0x00003a27 0f84ed080000 je 0x431a\n││││ 0x00003a2d e8fef8ffff call sym.imp.abort ; void abort(void)\n││││ ; CODE XREF from main (0x3a22)\n││`──> .localflag:\n││││ ; CODE XREF from main (0x3a22)\n││`──> 0x00003a32 be07000000 mov esi, 7\n[0x00003a04]>\n\n\n24.0.2 Flag Zones\nRizin offers flag zones, which lets you label different offsets on the scrollbar, for making it easier to navigate through large binaries. You can set a flag zone on the current seek using:\n[0x00003a04]> fz flag-zone-name\nSet e scr.scrollbar=1 and go to the Visual mode, to see your flag zone appear on the scrollbar on the right end of the window.\nSee fz? for more information.", "crumbs": [ "Basic Commands", - "23  Flags" + "24  Flags" ] }, { "objectID": "src/basic_commands/write.html", "href": "src/basic_commands/write.html", - "title": "24  Writing Data", + "title": "25  Writing Data", "section": "", - "text": "To be able to use Rizin in write mode, you need to load your binary as such: rizin -w bin.\nRizin can manipulate a loaded binary file in many ways. You can resize the file, move and copy/paste bytes, insert new bytes (shifting data to the end of the block or file), or simply overwrite bytes. New data may be given as a wide-string, assembler instructions, or the data may be read in from another file.\nResize the file using the r command. It accepts a numeric argument. A positive value sets a new size for the file. A negative one will truncate the file to the current seek position minus N bytes.\nr 1024 ; resize the file to 1024 bytes\nr -10 @ 33 ; strip 10 bytes at offset 33\nWrite bytes using the w command. It accepts multiple input formats like inline assembly, endian-friendly dwords, files, hexpair files, wide strings:\n[0x00404888]> w?\nUsage: w[?] # Write commands\n| w <string> # Write string\n| wB[-] # Set or unset bits with given value\n| wv[1248] # Write value of given size\n| w0 <len> # Write <len> bytes with value 0x00\n| w<1248><+-> [<n>] # Increment/decrement byte, word, ...\n| w6<de> # Write base64 [d]ecoded or [e]ncoded string\n| we<nsx> # Extend write operations (insert bytes instead of replacing)\n| wu <file> # Apply unified hex patch (see output of cu)\n| wr <len> # Write <len> random bytes\n| wc[j*-+ip?] # Write cache commands\n| wz <string> # Write zero-terminated string\n| wf[xfs] # Write data from file, socket, offset\n| ww <string> # Write wide (16-bit) little-endian string\n| wx[f] # Write hexadecimal data\n| wa[ifo] # Write opcodes\n| wb <hex> # Write in current block a hexstring cyclically\n| wm[-] # Set binary mask hexpair to be used as cyclic write mask\n| wo<?> # Write a block with a special operation\n| wD[/] # Write de Bruijn pattern\n| wd <src> <len> # Duplicate <len> bytes from <src> offset to current seek\n| ws <string> # Write 1 byte for length and then the string\n\nDetailed help for w <string> is provided by w??.\nSome examples:\n [0x00000000]> wx 123456 @ 0x8048300\n [0x00000000]> wv 0x8048123 @ 0x8049100\n [0x00000000]> wa \"jmp 0x8048320\"\n\n24.0.1 Write Over\nThe wo command (write over) has many subcommands, each combines the existing data with the new data using an operator. The command is applied to the current block. Supported operators include XOR, ADD, SUB…\n[0x4A13B8C0]> wo?\nUsage: wo<?> # Write a block with a special operation\n| wo2 # Swap the endianess of 2-bytes values in the current block\n| wo4 # Swap the endianess of 4-bytes values in the current block\n| wo8 # Swap the endianess of 8-bytes values in the current block\n| woa <value> # Add each existing byte in the block with the given <value>\n| woA <value> # Bitwise-and each existing byte in the block with the given <value>\n| wod <value> # Divide each existing byte in the block with the given <value>\n| wol <value> # Bitwise-shift-left each existing byte in the block with the given <value>\n| wom <value> # Multiply each existing byte in the block with the given <value>\n| woo <value> # Bitwise-or each existing byte in the block with the given <value>\n| wor <value> # Bitwise-shift-right each existing byte in the block with the given <value>\n| wos <value> # Subtract each existing byte in the block with the given <value>\n| wox <value> # Bitwise-xor each existing byte in the block with the given <value>\n| woe <from> <to> <step>=1 <value_size>=1 # Write a sequence repeatedly with values from <from> up to <to> in the block\n| woD <algo> <key> [<IV>] # Decrypt current block with given <algo>, <key> and optional <IV>\n| woE <algo> <key> [<IV>] # Encrypt current block with given <algo>, <key> and optional <IV>\n\nExamples:\n| woa 20 # Content before: 1122334455 ; Content after: 3142536475\n| wos 2021 # Content before: 1122334455 ; Content after: f101132335\n| wo4 # Content before: 1122334455667788; Content after: 4433221188776655\nIt is possible to implement cipher-algorithms using rizin core primitives and wo. A sample session performing xor(90) + add(01, 02):\n[0x7fcd6a891630]> px\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F\n0x7fcd6a891630 4889 e7e8 6839 0000 4989 c48b 05ef 1622\n0x7fcd6a891640 005a 488d 24c4 29c2 5248 89d6 4989 e548\n0x7fcd6a891650 83e4 f048 8b3d 061a 2200 498d 4cd5 1049\n0x7fcd6a891660 8d55 0831 ede8 06e2 0000 488d 15cf e600\n[0x7fcd6a891630]> wox 90\n[0x7fcd6a891630]> px\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F\n0x7fcd6a891630 d819 7778 d919 541b 90ca d81d c2d8 1946\n0x7fcd6a891640 1374 60d8 b290 d91d 1dc5 98a1 9090 d81d\n0x7fcd6a891650 90dc 197c 9f8f 1490 d81d 95d9 9f8f 1490\n0x7fcd6a891660 13d7 9491 9f8f 1490 13ff 9491 9f8f 1490\n[0x7fcd6a891630]> woa 01 02\n[0x7fcd6a891630]> px\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F\n0x7fcd6a891630 d91b 787a 91cc d91f 1476 61da 1ec7 99a3\n0x7fcd6a891640 91de 1a7e d91f 96db 14d9 9593 1401 9593\n0x7fcd6a891650 c4da 1a6d e89a d959 9192 9159 1cb1 d959\n0x7fcd6a891660 9192 79cb 81da 1652 81da 1456 a252 7c77", + "text": "To be able to use Rizin in write mode, you need to load your binary as such: rizin -w bin.\nRizin can manipulate a loaded binary file in many ways. You can resize the file, move and copy/paste bytes, insert new bytes (shifting data to the end of the block or file), or simply overwrite bytes. New data may be given as a wide-string, assembler instructions, or the data may be read in from another file.\nResize the file using the r command. It accepts a numeric argument. A positive value sets a new size for the file. A negative one will truncate the file to the current seek position minus N bytes.\nr 1024 ; resize the file to 1024 bytes\nr -10 @ 33 ; strip 10 bytes at offset 33\nWrite bytes using the w command. It accepts multiple input formats like inline assembly, endian-friendly dwords, files, hexpair files, wide strings:\n[0x00404888]> w?\nUsage: w[?] # Write commands\n| w <string> # Write string\n| wB[-] # Set or unset bits with given value\n| wv[1248] # Write value of given size\n| w0 <len> # Write <len> bytes with value 0x00\n| w<1248><+-> [<n>] # Increment/decrement byte, word, ...\n| w6<de> # Write base64 [d]ecoded or [e]ncoded string\n| we<nsx> # Extend write operations (insert bytes instead of replacing)\n| wu <file> # Apply unified hex patch (see output of cu)\n| wr <len> # Write <len> random bytes\n| wc[j*-+ip?] # Write cache commands\n| wz <string> # Write zero-terminated string\n| wf[xfs] # Write data from file, socket, offset\n| ww <string> # Write wide (16-bit) little-endian string\n| wx[f] # Write hexadecimal data\n| wa[ifo] # Write opcodes\n| wb <hex> # Write in current block a hexstring cyclically\n| wm[-] # Set binary mask hexpair to be used as cyclic write mask\n| wo<?> # Write a block with a special operation\n| wD[/] # Write de Bruijn pattern\n| wd <src> <len> # Duplicate <len> bytes from <src> offset to current seek\n| ws <string> # Write 1 byte for length and then the string\n\nDetailed help for w <string> is provided by w??.\nSome examples:\n [0x00000000]> wx 123456 @ 0x8048300\n [0x00000000]> wv 0x8048123 @ 0x8049100\n [0x00000000]> wa \"jmp 0x8048320\"\n\n25.0.1 Write Over\nThe wo command (write over) has many subcommands, each combines the existing data with the new data using an operator. The command is applied to the current block. Supported operators include XOR, ADD, SUB…\n[0x4A13B8C0]> wo?\nUsage: wo<?> # Write a block with a special operation\n| wo2 # Swap the endianess of 2-bytes values in the current block\n| wo4 # Swap the endianess of 4-bytes values in the current block\n| wo8 # Swap the endianess of 8-bytes values in the current block\n| woa <value> # Add each existing byte in the block with the given <value>\n| woA <value> # Bitwise-and each existing byte in the block with the given <value>\n| wod <value> # Divide each existing byte in the block with the given <value>\n| wol <value> # Bitwise-shift-left each existing byte in the block with the given <value>\n| wom <value> # Multiply each existing byte in the block with the given <value>\n| woo <value> # Bitwise-or each existing byte in the block with the given <value>\n| wor <value> # Bitwise-shift-right each existing byte in the block with the given <value>\n| wos <value> # Subtract each existing byte in the block with the given <value>\n| wox <value> # Bitwise-xor each existing byte in the block with the given <value>\n| woe <from> <to> <step>=1 <value_size>=1 # Write a sequence repeatedly with values from <from> up to <to> in the block\n| woD <algo> <key> [<IV>] # Decrypt current block with given <algo>, <key> and optional <IV>\n| woE <algo> <key> [<IV>] # Encrypt current block with given <algo>, <key> and optional <IV>\n\nExamples:\n| woa 20 # Content before: 1122334455 ; Content after: 3142536475\n| wos 2021 # Content before: 1122334455 ; Content after: f101132335\n| wo4 # Content before: 1122334455667788; Content after: 4433221188776655\nIt is possible to implement cipher-algorithms using rizin core primitives and wo. A sample session performing xor(90) + add(01, 02):\n[0x7fcd6a891630]> px\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F\n0x7fcd6a891630 4889 e7e8 6839 0000 4989 c48b 05ef 1622\n0x7fcd6a891640 005a 488d 24c4 29c2 5248 89d6 4989 e548\n0x7fcd6a891650 83e4 f048 8b3d 061a 2200 498d 4cd5 1049\n0x7fcd6a891660 8d55 0831 ede8 06e2 0000 488d 15cf e600\n[0x7fcd6a891630]> wox 90\n[0x7fcd6a891630]> px\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F\n0x7fcd6a891630 d819 7778 d919 541b 90ca d81d c2d8 1946\n0x7fcd6a891640 1374 60d8 b290 d91d 1dc5 98a1 9090 d81d\n0x7fcd6a891650 90dc 197c 9f8f 1490 d81d 95d9 9f8f 1490\n0x7fcd6a891660 13d7 9491 9f8f 1490 13ff 9491 9f8f 1490\n[0x7fcd6a891630]> woa 01 02\n[0x7fcd6a891630]> px\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F\n0x7fcd6a891630 d91b 787a 91cc d91f 1476 61da 1ec7 99a3\n0x7fcd6a891640 91de 1a7e d91f 96db 14d9 9593 1401 9593\n0x7fcd6a891650 c4da 1a6d e89a d959 9192 9159 1cb1 d959\n0x7fcd6a891660 9192 79cb 81da 1652 81da 1456 a252 7c77", "crumbs": [ "Basic Commands", - "24  Writing Data" + "25  Writing Data" ] }, { "objectID": "src/basic_commands/yank_paste.html", "href": "src/basic_commands/yank_paste.html", - "title": "25  Yank/Paste", + "title": "26  Yank/Paste", "section": "", "text": "Rizin has an internal clipboard to save and write portions of memory loaded from the current io layer.\nThis clipboard can be manipulated with the y command.\nThe two basic operations are\n\ncopy (yank)\npaste\n\nThe yank operation will read N bytes (specified by the argument) into the clipboard. We can later use the yy command to paste what we read before into a file.\nYou can yank/paste bytes in visual mode selecting them with the cursor mode (Vc) and then using the y and Y key bindings which are aliases for y and yy commands of the command-line interface.\n[0x00000000]> y?\nUsage: y[?] # Yank/paste bytes from/to memory\n| y[j*q] [<len>] # Yank bytes / Show yank contents\n| ye # Open cfg.editor to edit the clipboard\n| yf <len> <file> # Yank <len> bytes from file\n| yfa <file> # Yank whole file into clipboard\n| yp [<len>] # Print contents of clipboards as raw data\n| ys [<len>] # Print contents of clipboards as string\n| yt <len> <offset> # Copy <len> bytes from current seek to <offset>\n| ywx <string> # Yank from hexpairs string\n| yx [<len>] # Print contents of clipboard in hexadecimal\n| yy [<len>] # Paste <len> bytes from yank clipboard\n| yz [<len>] # Copy NULL-terminated string into clipboard\nSample session:\n[0x00000000]> s 0x100 ; seek at 0x100\n[0x00000100]> y 100 ; yanks 100 bytes from here\n[0x00000200]> s 0x200 ; seek 0x200\n[0x00000200]> yy ; pastes 100 bytes\nYou can perform a yank and paste in a single line by just using the yt command (yank-to). The syntax is as follows:\n[0x4A13B8C0]> x\n offset 0 1 2 3 4 5 6 7 8 9 A B 0123456789AB\n0x4A13B8C0, 89e0 e839 0700 0089 c7e8 e2ff ...9........\n0x4A13B8CC, ffff 81c3 eea6 0100 8b83 08ff ............\n0x4A13B8D8, ffff 5a8d 2484 29c2 ..Z.$.).\n\n[0x4A13B8C0]> yt 8 0x4A13B8CC @ 0x4A13B8C0\n\n[0x4A13B8C0]> x\n offset 0 1 2 3 4 5 6 7 8 9 A B 0123456789AB\n0x4A13B8C0, 89e0 e839 0700 0089 c7e8 e2ff ...9........\n0x4A13B8CC, 89e0 e839 0700 0089 8b83 08ff ...9........\n0x4A13B8D8, ffff 5a8d 2484 29c2 ..Z.$.).", "crumbs": [ "Basic Commands", - "25  Yank/Paste" + "26  Yank/Paste" ] }, { "objectID": "src/basic_commands/comparing_bytes.html", "href": "src/basic_commands/comparing_bytes.html", - "title": "26  Comparing Bytes", + "title": "27  Comparing Bytes", "section": "", "text": "For most generic reverse engineering tasks like finding the differences between two binary files, which bytes has changed, find differences in the graphs of the code analysis results, and other diffing operations you can just use rz-diff:\n$ rz-diff -h\nInside Rizin, the functionalities exposed by rz-diff are available with the c command.\nc (short for “compare”) allows you to compare arrays of bytes from different sources. The command accepts input in a number of formats and then compares it against values found at current seek position.\n[0x00001100]> c?\nUsage: c[?] # Compare block with given data\n| c[j] <string> # Compare an escaped <string> with data at current offset\n| c1 <addr> # Compare 8-bit data at current offset with the data at <addr>\n| ca[j] <addr> <n> # Compare <n> bytes of data at <addr> with the data at current offset\n| cb[j] <num> <n> # Compare <n> (up to 8) bytes at current offset with a number <num>\n| cc <addr> # Compare hexdump of data of block size at <addr> with the data at current offset\n| ccc <addr> # Show different lines between hexdump of a block of data at <addr> wth the data at current offset\n| ccd [<addr>] # Compare disassembly of block size at <addr> and at the current offset\n| cf[j] <file> # Compare the contents of <file> with the data at current offset\n| cu[1248d] # Unified diff commands\n| cw[lrux] # Compare watcher commands\n| cx[j] <hexpair> # Compare data at current offset with a hexpair string <hexpair> (also return in $?)\n| cX[j] <addr> # Compare hexdump of data of block size at <addr> with the data at current offset using hexdiff output\nTo compare memory contents at current seek position against a given string of values, use cx:\n[0x00001100]> p8 4\n7f454c46\n\n[0x00001100]> cx 7f 45 90 46\nCompare 3/4 equal bytes\n0x00001102 (byte=03) 90 ' ' -> 4c 'L'\nCompare 3/4 equal bytes (75%)\n[0x00001100]>\nAnother subcommand of the c command is cc which stands for “compare code”. To compare a byte sequence with a sequence in memory:\n[0x4A13B8C0]> cc 0x39e8e089 @ 0x4A13B8C0\nTo compare contents of two functions specified by their names:\n[0x08049A80]> cc sym.main2 @ sym.main\nThe number parameter can be math expressions which use flag names and anything allowed in an expression:\n[0x00000000]> cx 7f469046\n\nCompare 2/4 equal bytes\n0x00000001 (byte=02) 45 'E' -> 46 'F'\n0x00000002 (byte=03) 4c 'L' -> 90 ' '\nYou can use the compare command to find differences between a current block and a file previously dumped to a disk:\nrizin /usr/bin/true\n[0x00002680]> s 0\n[0x00000000]> cf /usr/bin/true\nCompare 256/256 equal bytes (100%)", "crumbs": [ "Basic Commands", - "26  Comparing Bytes" + "27  Comparing Bytes" ] }, { "objectID": "src/basic_commands/sdb.html", "href": "src/basic_commands/sdb.html", - "title": "27  SDB", + "title": "28  SDB", "section": "", - "text": "27.1 Usage example\nSDB stands for String DataBase. It’s a simple key-value database that only operates with strings created by pancake. It is used in many parts of rizin to have a disk and in-memory database which is small and fast to manage using it as a hashtable on steroids.\nSDB is a simple string key/value database based on djb’s cdb disk storage and supports JSON and arrays introspection.\nSDB supports:\nLet’s create a database!\nUsing arrays:\nLet’s play with json:\nUsing the command line without any disk database:\nRemove the database", + "text": "28.1 Usage example\nSDB stands for String DataBase. It’s a simple key-value database that only operates with strings created by pancake. It is used in many parts of rizin to have a disk and in-memory database which is small and fast to manage using it as a hashtable on steroids.\nSDB is a simple string key/value database based on djb’s cdb disk storage and supports JSON and arrays introspection.\nSDB supports:\nLet’s create a database!\nUsing arrays:\nLet’s play with json:\nUsing the command line without any disk database:\nRemove the database", "crumbs": [ "Basic Commands", - "27  SDB" + "28  SDB" ] }, { "objectID": "src/basic_commands/sdb.html#usage-example", "href": "src/basic_commands/sdb.html#usage-example", - "title": "27  SDB", + "title": "28  SDB", "section": "", "text": "$ sdb d hello=world\n$ sdb d hello\nworld\n\n$ sdb - '[]list=1,2' '[0]list' '[0]list=foo' '[]list' '[+1]list=bar'\n1\nfoo\n2\nfoo\nbar\n2\n\n$ sdb d g='{\"foo\":1,\"bar\":{\"cow\":3}}'\n$ sdb d g?bar.cow\n3\n$ sdb - user='{\"id\":123}' user?id=99 user?id\n99\n\n$ sdb - foo=bar foo a=3 +a -a\nbar\n4\n3\n\n$ sdb -\nfoo=bar\nfoo\nbar\na=3\n+a\n4\n-a\n3\n\n$ rm -f d", "crumbs": [ "Basic Commands", - "27  SDB" + "28  SDB" ] }, { "objectID": "src/basic_commands/sdb.html#so-what", "href": "src/basic_commands/sdb.html#so-what", - "title": "27  SDB", - "section": "27.2 So what ?", - "text": "27.2 So what ?\nSo, you can now do this inside your rizin sessions!\nLet’s take a simple binary hello_world, and check what is already sdbized.\n$ rizin -A hello_world\n[0x00001100]> k ** # list namespaces under analysis\nanalysis\nbin\ndebug\nsyscall\n\n[0x00001100]> k bin/**\ncur\nfd.3", + "title": "28  SDB", + "section": "28.2 So what ?", + "text": "28.2 So what ?\nSo, you can now do this inside your rizin sessions!\nLet’s take a simple binary hello_world, and check what is already sdbized.\n$ rizin -A hello_world\n[0x00001100]> k ** # list namespaces under analysis\nanalysis\nbin\ndebug\nsyscall\n\n[0x00001100]> k bin/**\ncur\nfd.3", "crumbs": [ "Basic Commands", - "27  SDB" + "28  SDB" ] }, { "objectID": "src/basic_commands/sdb.html#more-examples", "href": "src/basic_commands/sdb.html#more-examples", - "title": "27  SDB", - "section": "27.3 More Examples", - "text": "27.3 More Examples\nList namespaces\nk **\nList sub-namespaces\nk analysis/**\nList keys\nk *\nk analysis/*\nSet a key\nk foo=bar\nGet the value of a key\nk foo\nList all syscalls\nk syscall/*~^0x\nList all comments\nk analysis/meta/*~.C.\nShow a comment at given offset:\nk %analysis/meta/[1]meta.C.0x100005000", + "title": "28  SDB", + "section": "28.3 More Examples", + "text": "28.3 More Examples\nList namespaces\nk **\nList sub-namespaces\nk analysis/**\nList keys\nk *\nk analysis/*\nSet a key\nk foo=bar\nGet the value of a key\nk foo\nList all syscalls\nk syscall/*~^0x\nList all comments\nk analysis/meta/*~.C.\nShow a comment at given offset:\nk %analysis/meta/[1]meta.C.0x100005000", "crumbs": [ "Basic Commands", - "27  SDB" + "28  SDB" ] }, { "objectID": "src/basic_commands/dietline.html", "href": "src/basic_commands/dietline.html", - "title": "28  Dietline", + "title": "29  Dietline", "section": "", - "text": "29 Autocompletion\nRizin comes with the lean readline-like input capability through the lean library to handle the command edition and history navigation. It allows users to perform cursor movements, search the history, and implements autocompletion. Moreover, due to the rizin portability, dietline provides the uniform experience among all supported platforms. It is used in all rizin subshells - main prompt, SDB shell, visual prompt, and offsets prompt. It also implements the most common features and keybindings compatible with the GNU Readline.\nDietline supports two major configuration modes : Emacs-mode and Vi-mode.\nIt also supports the famous Ctrl-R reverse history search. Using TAB key it allows to scroll through the autocompletion options.\nIn the every shell and rizin command autocompletion is supported. There are multiple modes of it - files, flags, and SDB keys/namespaces. To provide the easy way to select possible completion options the scrollable popup widget is available. It can be enabled with scr.prompt.popup, just set it to the true (as such: e scr.prompt.popup=true).", + "text": "30 Autocompletion\nRizin comes with the lean readline-like input capability through the lean library to handle the command edition and history navigation. It allows users to perform cursor movements, search the history, and implements autocompletion. Moreover, due to the rizin portability, dietline provides the uniform experience among all supported platforms. It is used in all rizin subshells - main prompt, SDB shell, visual prompt, and offsets prompt. It also implements the most common features and keybindings compatible with the GNU Readline.\nDietline supports two major configuration modes : Emacs-mode and Vi-mode.\nIt also supports the famous Ctrl-R reverse history search. Using TAB key it allows to scroll through the autocompletion options.\nIn the every shell and rizin command autocompletion is supported. There are multiple modes of it - files, flags, and SDB keys/namespaces. To provide the easy way to select possible completion options the scrollable popup widget is available. It can be enabled with scr.prompt.popup, just set it to the true (as such: e scr.prompt.popup=true).", "crumbs": [ "Basic Commands", - "28  Dietline" + "29  Dietline" ] }, { "objectID": "src/basic_commands/dietline.html#moving", "href": "src/basic_commands/dietline.html#moving", - "title": "28  Dietline", - "section": "30.1 Moving", - "text": "30.1 Moving\n\nCtrl-a - move to the beginning of the line\nCtrl-e - move to the end of the line\nCtrl-b - move one character backward\nCtrl-f - move one character forward", + "title": "29  Dietline", + "section": "31.1 Moving", + "text": "31.1 Moving\n\nCtrl-a - move to the beginning of the line\nCtrl-e - move to the end of the line\nCtrl-b - move one character backward\nCtrl-f - move one character forward", "crumbs": [ "Basic Commands", - "28  Dietline" + "29  Dietline" ] }, { "objectID": "src/basic_commands/dietline.html#deleting", "href": "src/basic_commands/dietline.html#deleting", - "title": "28  Dietline", - "section": "30.2 Deleting", - "text": "30.2 Deleting\n\nCtrl-w - delete the previous word\nCtrl-u - delete the whole line\nCtrl-h - delete a character to the left\nCtrl-d - delete a character to the right\nAlt-d - cuts the character after the cursor", + "title": "29  Dietline", + "section": "31.2 Deleting", + "text": "31.2 Deleting\n\nCtrl-w - delete the previous word\nCtrl-u - delete the whole line\nCtrl-h - delete a character to the left\nCtrl-d - delete a character to the right\nAlt-d - cuts the character after the cursor", "crumbs": [ "Basic Commands", - "28  Dietline" + "29  Dietline" ] }, { "objectID": "src/basic_commands/dietline.html#killing-and-yanking", "href": "src/basic_commands/dietline.html#killing-and-yanking", - "title": "28  Dietline", - "section": "30.3 Killing and Yanking", - "text": "30.3 Killing and Yanking\n\nCtrl-k - kill the text from point to the end of the line.\nCtrl-x - kill backward from the cursor to the beginning of the current line.\nCtrl-t - kill from point to the end of the current word, or if between words, to the end of the next word. Word boundaries are the same as forward-word.\nCtrl-w - kill the word behind point, using white space as a word boundary. The killed text is saved on the kill-ring.\nCtrl-y - yank the top of the kill ring into the buffer at point.\nCtrl-] - rotate the kill-ring, and yank the new top. You can only do this if the prior command is yank or yank-pop.", + "title": "29  Dietline", + "section": "31.3 Killing and Yanking", + "text": "31.3 Killing and Yanking\n\nCtrl-k - kill the text from point to the end of the line.\nCtrl-x - kill backward from the cursor to the beginning of the current line.\nCtrl-t - kill from point to the end of the current word, or if between words, to the end of the next word. Word boundaries are the same as forward-word.\nCtrl-w - kill the word behind point, using white space as a word boundary. The killed text is saved on the kill-ring.\nCtrl-y - yank the top of the kill ring into the buffer at point.\nCtrl-] - rotate the kill-ring, and yank the new top. You can only do this if the prior command is yank or yank-pop.", "crumbs": [ "Basic Commands", - "28  Dietline" + "29  Dietline" ] }, { "objectID": "src/basic_commands/dietline.html#history", "href": "src/basic_commands/dietline.html#history", - "title": "28  Dietline", - "section": "30.4 History", - "text": "30.4 History\n\nCtrl-r - the reverse search in the command history", + "title": "29  Dietline", + "section": "31.4 History", + "text": "31.4 History\n\nCtrl-r - the reverse search in the command history", "crumbs": [ "Basic Commands", - "28  Dietline" + "29  Dietline" ] }, { "objectID": "src/basic_commands/dietline.html#entering-command-modes", "href": "src/basic_commands/dietline.html#entering-command-modes", - "title": "28  Dietline", - "section": "31.1 Entering command modes", - "text": "31.1 Entering command modes\n\nESC - enter into the control mode\ni - enter into the insert mode", + "title": "29  Dietline", + "section": "32.1 Entering command modes", + "text": "32.1 Entering command modes\n\nESC - enter into the control mode\ni - enter into the insert mode", "crumbs": [ "Basic Commands", - "28  Dietline" + "29  Dietline" ] }, { "objectID": "src/basic_commands/dietline.html#moving-1", "href": "src/basic_commands/dietline.html#moving-1", - "title": "28  Dietline", - "section": "31.2 Moving", - "text": "31.2 Moving\n\nj - acts like up arrow key\nk - acts like down arrow key\na - move cursor forward and enter into insert mode\nI - move to the beginning of the line and enter into insert mode\nA - move to the end of the line and enter into insert mode\n^ - move to the beginning of the line\n0 - move to the beginning of the line\n$ - move to the end of the line\nh - move one character backward\nl - move one character forward", + "title": "29  Dietline", + "section": "32.2 Moving", + "text": "32.2 Moving\n\nj - acts like up arrow key\nk - acts like down arrow key\na - move cursor forward and enter into insert mode\nI - move to the beginning of the line and enter into insert mode\nA - move to the end of the line and enter into insert mode\n^ - move to the beginning of the line\n0 - move to the beginning of the line\n$ - move to the end of the line\nh - move one character backward\nl - move one character forward", "crumbs": [ "Basic Commands", - "28  Dietline" + "29  Dietline" ] }, { "objectID": "src/basic_commands/dietline.html#deleting-and-yanking", "href": "src/basic_commands/dietline.html#deleting-and-yanking", - "title": "28  Dietline", - "section": "31.3 Deleting and Yanking", - "text": "31.3 Deleting and Yanking\n\nx - cuts the character\ndw - delete the current word\ndiw - deletes the current word.\ndb - delete the previous word\nD - delete the whole line\ndh - delete a character to the left\ndl - delete a character to the right\nd$ - kill the text from point to the end of the line.\nd^ - kill backward from the cursor to the beginning of the current line.\nde - kill from point to the end of the current word, or if between words, to the end of the next word. Word boundaries are the same as forward-word.\np - yank the top of the kill ring into the buffer at point.\nc - acts similar to d based commands, but goes into insert mode in the end by prefixing the commands with numbers, the command is performed multiple times.\n\nIf you are finding it hard to keep track of which mode you are in, just enter e scr.prompt.mode=true to update the color of the prompt based on the vi-mode.", + "title": "29  Dietline", + "section": "32.3 Deleting and Yanking", + "text": "32.3 Deleting and Yanking\n\nx - cuts the character\ndw - delete the current word\ndiw - deletes the current word.\ndb - delete the previous word\nD - delete the whole line\ndh - delete a character to the left\ndl - delete a character to the right\nd$ - kill the text from point to the end of the line.\nd^ - kill backward from the cursor to the beginning of the current line.\nde - kill from point to the end of the current word, or if between words, to the end of the next word. Word boundaries are the same as forward-word.\np - yank the top of the kill ring into the buffer at point.\nc - acts similar to d based commands, but goes into insert mode in the end by prefixing the commands with numbers, the command is performed multiple times.\n\nIf you are finding it hard to keep track of which mode you are in, just enter e scr.prompt.mode=true to update the color of the prompt based on the vi-mode.", "crumbs": [ "Basic Commands", - "28  Dietline" + "29  Dietline" ] }, { "objectID": "src/visual_mode/intro.html", "href": "src/visual_mode/intro.html", - "title": "29  Visual Mode", + "title": "30  Visual Mode", "section": "", - "text": "29.1 Navigation\nThe visual mode is a more user-friendly interface alternative to Rizin’s command-line prompt. It allows easy navigation, has a cursor mode for selecting bytes, and offers numerous key bindings to simplify debugger use. To enter visual mode, use V command. To exit from it back to command line, press q.\nNavigation can be done using HJKL or arrow keys and PgUp/PgDown keys. It also understands usual Home/End keys. Like in Vim the movements can be repeated by preceding the navigation key with the number, for example 5j will move down for 5 lines, or 2l will move 2 characters right.", + "text": "30.1 Navigation\nThe visual mode is a more user-friendly interface alternative to Rizin’s command-line prompt. It allows easy navigation, has a cursor mode for selecting bytes, and offers numerous key bindings to simplify debugger use. To enter visual mode, use V command. To exit from it back to command line, press q.\nNavigation can be done using HJKL or arrow keys and PgUp/PgDown keys. It also understands usual Home/End keys. Like in Vim the movements can be repeated by preceding the navigation key with the number, for example 5j will move down for 5 lines, or 2l will move 2 characters right.", "crumbs": [ "Visual mode", - "29  Visual Mode" + "30  Visual Mode" ] }, { "objectID": "src/visual_mode/intro.html#navigation", "href": "src/visual_mode/intro.html#navigation", - "title": "29  Visual Mode", + "title": "30  Visual Mode", "section": "", "text": "Visual Mode", "crumbs": [ "Visual mode", - "29  Visual Mode" + "30  Visual Mode" ] }, { "objectID": "src/visual_mode/intro.html#print-modes-aka-panels", "href": "src/visual_mode/intro.html#print-modes-aka-panels", - "title": "29  Visual Mode", - "section": "29.2 Print modes aka panels", - "text": "29.2 Print modes aka panels\nThe Visual mode uses “print modes” which are basically different panel that you can rotate. By default, those are:\n↻ Hexdump panel -> Disassembly panel → Debugger panel → Hexadecimal words dump panel → Hex-less hexdump panel → Op analysis color map panel → Annotated hexdump panel ↺.\nNotice that the top of the panel contains the command which is used, for example for the disassembly panel:\n[0x00404890 16% 120 /bin/ls]> pd $r @ entry0", + "title": "30  Visual Mode", + "section": "30.2 Print modes aka panels", + "text": "30.2 Print modes aka panels\nThe Visual mode uses “print modes” which are basically different panel that you can rotate. By default, those are:\n↻ Hexdump panel -> Disassembly panel → Debugger panel → Hexadecimal words dump panel → Hex-less hexdump panel → Op analysis color map panel → Annotated hexdump panel ↺.\nNotice that the top of the panel contains the command which is used, for example for the disassembly panel:\n[0x00404890 16% 120 /bin/ls]> pd $r @ entry0", "crumbs": [ "Visual mode", - "29  Visual Mode" + "30  Visual Mode" ] }, { "objectID": "src/visual_mode/intro.html#getting-help", "href": "src/visual_mode/intro.html#getting-help", - "title": "29  Visual Mode", - "section": "29.3 Getting Help", - "text": "29.3 Getting Help\nTo see help on all key bindings defined for visual mode, press ?:\nVisual mode help:\n ? show this help\n ?? show the user-friendly hud\n % in cursor mode finds matching pair, or toggle autoblocksz\n @ redraw screen every 1s (multi-user view)\n ^ seek to the beginning of the function\n ! enter into the visual panels mode\n _ enter the flag/comment/functions/.. hud (same as VF_)\n = set cmd.vprompt (top row)\n | set cmd.cprompt (right column)\n . seek to program counter\n \\ toggle visual split mode\n \" toggle the column mode (uses pC..)\n / in cursor mode search in current block\n :cmd run rizin command\n ;[-]cmt add/remove comment\n 0 seek to beginning of current function\n [1-9] follow jmp/call identified by shortcut (like ;[1])\n ,file add a link to the text file\n /*+-[] change block size, [] = resize hex.cols\n </> seek aligned to block size (seek cursor in cursor mode)\n a/A (a)ssemble code, visual (A)ssembler\n b browse symbols, flags, configurations, classes, ...\n B toggle breakpoint\n c/C toggle (c)ursor and (C)olors\n d[f?] define function, data, code, ..\n D enter visual diff mode (set diff.from/to\n e edit eval configuration variables\n f/F set/unset or browse flags. f- to unset, F to browse, ..\n gG go seek to begin and end of file (0-$s)\n hjkl move around (or HJKL) (left-down-up-right)\n i insert hex or string (in hexdump) use tab to toggle\n mK/'K mark/go to Key (any key)\n n/N seek next/prev function/flag/hit (scr.nkey)\n g go/seek to given offset\n O toggle asm.pseudo and asm.esil\n p/P rotate print modes (hex, disasm, debug, words, buf)\n q back to rizin shell\n r refresh screen / in cursor mode browse comments\n R randomize color palette (ecr)\n sS step / step over\n t browse types\n uU undo/redo seek\n v visual function/vars code analysis menu\n V (V)iew graph using cmd.graph (agv?)\n wW seek cursor to next/prev word\n xX show xrefs/refs of current function from/to data/code\n yY copy and paste selection\n z fold/unfold comments in disassembly\n Z toggle zoom mode\n Enter follow address of jump/call\nFunction Keys: (See 'e key.'), defaults to:\n F2 toggle breakpoint\n F4 run to cursor\n F7 single step\n F8 step over\n F9 continue", + "title": "30  Visual Mode", + "section": "30.3 Getting Help", + "text": "30.3 Getting Help\nTo see help on all key bindings defined for visual mode, press ?:\nVisual mode help:\n ? show this help\n ?? show the user-friendly hud\n % in cursor mode finds matching pair, or toggle autoblocksz\n @ redraw screen every 1s (multi-user view)\n ^ seek to the beginning of the function\n ! enter into the visual panels mode\n _ enter the flag/comment/functions/.. hud (same as VF_)\n = set cmd.vprompt (top row)\n | set cmd.cprompt (right column)\n . seek to program counter\n \\ toggle visual split mode\n \" toggle the column mode (uses pC..)\n / in cursor mode search in current block\n :cmd run rizin command\n ;[-]cmt add/remove comment\n 0 seek to beginning of current function\n [1-9] follow jmp/call identified by shortcut (like ;[1])\n ,file add a link to the text file\n /*+-[] change block size, [] = resize hex.cols\n </> seek aligned to block size (seek cursor in cursor mode)\n a/A (a)ssemble code, visual (A)ssembler\n b browse symbols, flags, configurations, classes, ...\n B toggle breakpoint\n c/C toggle (c)ursor and (C)olors\n d[f?] define function, data, code, ..\n D enter visual diff mode (set diff.from/to\n e edit eval configuration variables\n f/F set/unset or browse flags. f- to unset, F to browse, ..\n gG go seek to begin and end of file (0-$s)\n hjkl move around (or HJKL) (left-down-up-right)\n i insert hex or string (in hexdump) use tab to toggle\n mK/'K mark/go to Key (any key)\n n/N seek next/prev function/flag/hit (scr.nkey)\n g go/seek to given offset\n O toggle asm.pseudo and asm.esil\n p/P rotate print modes (hex, disasm, debug, words, buf)\n q back to rizin shell\n r refresh screen / in cursor mode browse comments\n R randomize color palette (ecr)\n sS step / step over\n t browse types\n uU undo/redo seek\n v visual function/vars code analysis menu\n V (V)iew graph using cmd.graph (agv?)\n wW seek cursor to next/prev word\n xX show xrefs/refs of current function from/to data/code\n yY copy and paste selection\n z fold/unfold comments in disassembly\n Z toggle zoom mode\n Enter follow address of jump/call\nFunction Keys: (See 'e key.'), defaults to:\n F2 toggle breakpoint\n F4 run to cursor\n F7 single step\n F8 step over\n F9 continue", "crumbs": [ "Visual mode", - "29  Visual Mode" + "30  Visual Mode" ] }, { "objectID": "src/visual_mode/visual_disassembly.html", "href": "src/visual_mode/visual_disassembly.html", - "title": "30  Visual Disassembly", + "title": "31  Visual Disassembly", "section": "", - "text": "30.1 Navigation\nMove within the Disassembly using arrow keys or hjkl. Use g to seek directly to a flag or an offset, type it when requested by the prompt: [offset]>. Follow a jump or a call using the number of your keyboard [0-9] and the number on the right in disassembly to follow a call or a jump. In this example typing 1 on the keyboard would follow the call to sym.imp.__libc_start_main and therefore, seek at the offset of this symbol.\nSeek back to the previous location using u, U will allow you to redo the seek.", + "text": "31.1 Navigation\nMove within the Disassembly using arrow keys or hjkl. Use g to seek directly to a flag or an offset, type it when requested by the prompt: [offset]>. Follow a jump or a call using the number of your keyboard [0-9] and the number on the right in disassembly to follow a call or a jump. In this example typing 1 on the keyboard would follow the call to sym.imp.__libc_start_main and therefore, seek at the offset of this symbol.\nSeek back to the previous location using u, U will allow you to redo the seek.", "crumbs": [ "Visual mode", - "30  Visual Disassembly" + "31  Visual Disassembly" ] }, { "objectID": "src/visual_mode/visual_disassembly.html#navigation", "href": "src/visual_mode/visual_disassembly.html#navigation", - "title": "30  Visual Disassembly", + "title": "31  Visual Disassembly", "section": "", "text": "0x00404894 e857dcffff call sym.imp.__libc_start_main ;[1]", "crumbs": [ "Visual mode", - "30  Visual Disassembly" + "31  Visual Disassembly" ] }, { "objectID": "src/visual_mode/visual_disassembly.html#d-as-define", "href": "src/visual_mode/visual_disassembly.html#d-as-define", - "title": "30  Visual Disassembly", - "section": "30.2 d as define", - "text": "30.2 d as define\nd can be used to change the type of data of the current block, several basic types/structures are available as well as more advanced one using pf template:\nd → ...\n0x004048f7 48c1e83f shr rax, 0x3f\nd → b\n0x004048f7 .byte 0x48\nd → B\n0x004048f7 .word 0xc148\nd → d\n0x004048f7 hex length=165 delta=0\n0x004048f7 48c1 e83f 4801 c648 d1fe 7415 b800 0000\n...\nTo improve code readability you can change how Rizin presents numerical values in disassembly, by default most disassembly display numerical value as hexadecimal. Sometimes you would like to view it as a decimal, binary or even custom defined constant. To change value format you can use d following by i then choose what base to work in, this is the equivalent to ahi:\nd → i → ...\n0x004048f7 48c1e83f shr rax, 0x3f\nd → i → 10\n0x004048f7 48c1e83f shr rax, 63\nd → i → 2\n0x004048f7 48c1e83f shr rax, '?'\n\n30.2.1 Usage of the Cursor for Inserting/Patching…\nRemember that, to be able to actually edit files loaded in rizin, you have to start it with the -w option. Otherwise, a file is opened in read-only mode.\nPressing lowercase c toggles the cursor mode. When this mode is active, the currently selected byte (or byte range) is highlighted.\n\n\n\nCursor at 0x00404896\n\n\nThe cursor is used to select a range of bytes or simply to point to a byte. You can use the cursor to create a named flag at specific location. To do so, seek to the required position, then press f and enter a name for a flag. If the file was opened in write mode using the -w flag or the o+ command, you can also use the cursor to overwrite a selected range with new values. To do so, select a range of bytes (with HJKL and SHIFT key pressed), then press i and enter the hexpair values for the new data. The data will be repeated as needed to fill the range selected. For example:\n<select 10 bytes in visual mode using SHIFT+HJKL>\n<press 'i' and then enter '12 34'>\nThe 10 bytes you have selected will be changed to “12 34 12 34 12 …”.\nThe Visual Assembler is a feature that provides a live-preview while you type in new instructions to patch into the disassembly. To use it, seek or place the cursor at the wanted location and hit the ‘A’ key. To provide multiple instructions, separate them with semicolons, ;.", + "title": "31  Visual Disassembly", + "section": "31.2 d as define", + "text": "31.2 d as define\nd can be used to change the type of data of the current block, several basic types/structures are available as well as more advanced one using pf template:\nd → ...\n0x004048f7 48c1e83f shr rax, 0x3f\nd → b\n0x004048f7 .byte 0x48\nd → B\n0x004048f7 .word 0xc148\nd → d\n0x004048f7 hex length=165 delta=0\n0x004048f7 48c1 e83f 4801 c648 d1fe 7415 b800 0000\n...\nTo improve code readability you can change how Rizin presents numerical values in disassembly, by default most disassembly display numerical value as hexadecimal. Sometimes you would like to view it as a decimal, binary or even custom defined constant. To change value format you can use d following by i then choose what base to work in, this is the equivalent to ahi:\nd → i → ...\n0x004048f7 48c1e83f shr rax, 0x3f\nd → i → 10\n0x004048f7 48c1e83f shr rax, 63\nd → i → 2\n0x004048f7 48c1e83f shr rax, '?'\n\n31.2.1 Usage of the Cursor for Inserting/Patching…\nRemember that, to be able to actually edit files loaded in rizin, you have to start it with the -w option. Otherwise, a file is opened in read-only mode.\nPressing lowercase c toggles the cursor mode. When this mode is active, the currently selected byte (or byte range) is highlighted.\n\n\n\nCursor at 0x00404896\n\n\nThe cursor is used to select a range of bytes or simply to point to a byte. You can use the cursor to create a named flag at specific location. To do so, seek to the required position, then press f and enter a name for a flag. If the file was opened in write mode using the -w flag or the o+ command, you can also use the cursor to overwrite a selected range with new values. To do so, select a range of bytes (with HJKL and SHIFT key pressed), then press i and enter the hexpair values for the new data. The data will be repeated as needed to fill the range selected. For example:\n<select 10 bytes in visual mode using SHIFT+HJKL>\n<press 'i' and then enter '12 34'>\nThe 10 bytes you have selected will be changed to “12 34 12 34 12 …”.\nThe Visual Assembler is a feature that provides a live-preview while you type in new instructions to patch into the disassembly. To use it, seek or place the cursor at the wanted location and hit the ‘A’ key. To provide multiple instructions, separate them with semicolons, ;.", "crumbs": [ "Visual mode", - "30  Visual Disassembly" + "31  Visual Disassembly" ] }, { "objectID": "src/visual_mode/visual_disassembly.html#xref", "href": "src/visual_mode/visual_disassembly.html#xref", - "title": "30  Visual Disassembly", - "section": "30.3 XREF", - "text": "30.3 XREF\nWhen rizin has discovered a XREF during the analysis, it will show you the information in the Visual Disassembly using XREF tag:\n; DATA XREF from 0x00402e0e (unk)\nstr.David_MacKenzie:\nTo see where this string is called, press x, if you want to jump to the location where the data is used then press the corresponding number [0-9] on your keyboard. (This functionality is similar to axt)\nX corresponds to the reverse operation aka axf.", + "title": "31  Visual Disassembly", + "section": "31.3 XREF", + "text": "31.3 XREF\nWhen rizin has discovered a XREF during the analysis, it will show you the information in the Visual Disassembly using XREF tag:\n; DATA XREF from 0x00402e0e (unk)\nstr.David_MacKenzie:\nTo see where this string is called, press x, if you want to jump to the location where the data is used then press the corresponding number [0-9] on your keyboard. (This functionality is similar to axt)\nX corresponds to the reverse operation aka axf.", "crumbs": [ "Visual mode", - "30  Visual Disassembly" + "31  Visual Disassembly" ] }, { "objectID": "src/visual_mode/visual_disassembly.html#function-argument-display", "href": "src/visual_mode/visual_disassembly.html#function-argument-display", - "title": "30  Visual Disassembly", - "section": "30.4 Function Argument display", - "text": "30.4 Function Argument display\nTo enable this view use this config var e dbg.funcarg=true\n\n\n\nfuncarg", + "title": "31  Visual Disassembly", + "section": "31.4 Function Argument display", + "text": "31.4 Function Argument display\nTo enable this view use this config var e dbg.funcarg=true\n\n\n\nfuncarg", "crumbs": [ "Visual mode", - "30  Visual Disassembly" + "31  Visual Disassembly" ] }, { "objectID": "src/visual_mode/visual_disassembly.html#add-a-comment", "href": "src/visual_mode/visual_disassembly.html#add-a-comment", - "title": "30  Visual Disassembly", - "section": "30.5 Add a comment", - "text": "30.5 Add a comment\nTo add a comment press ;.", + "title": "31  Visual Disassembly", + "section": "31.5 Add a comment", + "text": "31.5 Add a comment\nTo add a comment press ;.", "crumbs": [ "Visual mode", - "30  Visual Disassembly" + "31  Visual Disassembly" ] }, { "objectID": "src/visual_mode/visual_disassembly.html#type-other-commands", "href": "src/visual_mode/visual_disassembly.html#type-other-commands", - "title": "30  Visual Disassembly", - "section": "30.6 Type other commands", - "text": "30.6 Type other commands\nQuickly type commands using :.", + "title": "31  Visual Disassembly", + "section": "31.6 Type other commands", + "text": "31.6 Type other commands\nQuickly type commands using :.", "crumbs": [ "Visual mode", - "30  Visual Disassembly" + "31  Visual Disassembly" ] }, { "objectID": "src/visual_mode/visual_disassembly.html#search", "href": "src/visual_mode/visual_disassembly.html#search", - "title": "30  Visual Disassembly", - "section": "30.7 Search", - "text": "30.7 Search\n/: allows highlighting of strings in the current display. :cmd allows you to use one of the “/?” commands that perform more specialized searches.", + "title": "31  Visual Disassembly", + "section": "31.7 Search", + "text": "31.7 Search\n/: allows highlighting of strings in the current display. :cmd allows you to use one of the “/?” commands that perform more specialized searches.", "crumbs": [ "Visual mode", - "30  Visual Disassembly" + "31  Visual Disassembly" ] }, { "objectID": "src/visual_mode/visual_disassembly.html#the-huds", "href": "src/visual_mode/visual_disassembly.html#the-huds", - "title": "30  Visual Disassembly", - "section": "30.8 The HUDS", - "text": "30.8 The HUDS\n\n30.8.1 The “UserFriendly HUD”\nThe “UserFriendly HUD” can be accessed using the ?? key-combination. This HUD acts as an interactive Cheat Sheet that one can use to more easily find and execute commands. This HUD is particularly useful for newcomers. For experienced users, the other HUDS which are more activity-specific may be more useful.\n\n\n30.8.2 The “flag/comment/functions/.. HUD”\nThis HUD can be displayed using the _ key, it shows a list of all the flags defined and lets you jump to them. Using the keyboard you can quickly filter the list down to a flag that contains a specific pattern.\nHud input mode can be closed using ^C. It will also exit when backspace is pressed when the user input string is empty.", + "title": "31  Visual Disassembly", + "section": "31.8 The HUDS", + "text": "31.8 The HUDS\n\n31.8.1 The “UserFriendly HUD”\nThe “UserFriendly HUD” can be accessed using the ?? key-combination. This HUD acts as an interactive Cheat Sheet that one can use to more easily find and execute commands. This HUD is particularly useful for newcomers. For experienced users, the other HUDS which are more activity-specific may be more useful.\n\n\n31.8.2 The “flag/comment/functions/.. HUD”\nThis HUD can be displayed using the _ key, it shows a list of all the flags defined and lets you jump to them. Using the keyboard you can quickly filter the list down to a flag that contains a specific pattern.\nHud input mode can be closed using ^C. It will also exit when backspace is pressed when the user input string is empty.", "crumbs": [ "Visual mode", - "30  Visual Disassembly" + "31  Visual Disassembly" ] }, { "objectID": "src/visual_mode/visual_disassembly.html#tweaking-the-disassembly", "href": "src/visual_mode/visual_disassembly.html#tweaking-the-disassembly", - "title": "30  Visual Disassembly", - "section": "30.9 Tweaking the Disassembly", - "text": "30.9 Tweaking the Disassembly\nThe disassembly’s look-and-feel is controlled using the “asm.* configuration keys, which can be changed using the e command. All configuration keys can also be edited through the Visual Configuration Editor.", + "title": "31  Visual Disassembly", + "section": "31.9 Tweaking the Disassembly", + "text": "31.9 Tweaking the Disassembly\nThe disassembly’s look-and-feel is controlled using the “asm.* configuration keys, which can be changed using the e command. All configuration keys can also be edited through the Visual Configuration Editor.", "crumbs": [ "Visual mode", - "30  Visual Disassembly" + "31  Visual Disassembly" ] }, { "objectID": "src/visual_mode/visual_disassembly.html#visual-configuration-editor", "href": "src/visual_mode/visual_disassembly.html#visual-configuration-editor", - "title": "30  Visual Disassembly", - "section": "30.10 Visual Configuration Editor", - "text": "30.10 Visual Configuration Editor\nThis HUD can be accessed using the e key in visual mode. The editor allows you to easily examine and change Rizin’s configuration. For example, if you want to change something about the disassembly display, select asm from the list, navigate to the item you wish to modify it, then select it by hitting Enter. If the item is a boolean variable, it will toggle, otherwise you will be prompted to provide a new value.\n\n\n\nFirst Select asm\n\n\nExample switch to pseudo disassembly:\n\n\n\nPseudo disassembly disabled\n\n\n\n\n\nPseudo disassembly enabled\n\n\nFollowing are some example of eval variable related to disassembly.", + "title": "31  Visual Disassembly", + "section": "31.10 Visual Configuration Editor", + "text": "31.10 Visual Configuration Editor\nThis HUD can be accessed using the e key in visual mode. The editor allows you to easily examine and change Rizin’s configuration. For example, if you want to change something about the disassembly display, select asm from the list, navigate to the item you wish to modify it, then select it by hitting Enter. If the item is a boolean variable, it will toggle, otherwise you will be prompted to provide a new value.\n\n\n\nFirst Select asm\n\n\nExample switch to pseudo disassembly:\n\n\n\nPseudo disassembly disabled\n\n\n\n\n\nPseudo disassembly enabled\n\n\nFollowing are some example of eval variable related to disassembly.", "crumbs": [ "Visual mode", - "30  Visual Disassembly" + "31  Visual Disassembly" ] }, { "objectID": "src/visual_mode/visual_disassembly.html#examples", "href": "src/visual_mode/visual_disassembly.html#examples", - "title": "30  Visual Disassembly", - "section": "30.11 Examples", - "text": "30.11 Examples\n\n30.11.0.1 asm.arch: Change Architecture && asm.bits: Word size in bits at assembler\nYou can view the list of all arch using e asm.arch=?\ne asm.arch=dalvik\n0x00404870 31ed4989 cmp-long v237, v73, v137\n0x00404874 d15e4889 rsub-int v14, v5, 0x8948\n0x00404878 e24883e4 ushr-int/lit8 v72, v131, 0xe4\n0x0040487c f0505449c7c0 +invoke-object-init-range {}, method+18772 ;[0]\n0x00404882 90244100 add-int v36, v65, v0\ne asm.bits=16\n0000:4870 31ed xor bp, bp\n0000:4872 49 dec cx\n0000:4873 89d1 mov cx, dx\n0000:4875 5e pop si\n0000:4876 48 dec ax\n0000:4877 89e2 mov dx, sp\nThis latest operation can also be done using & in Visual mode.\n\n\n30.11.0.2 asm.pseudo: Enable pseudo syntax\ne asm.pseudo=true\n0x00404870 31ed ebp = 0\n0x00404872 4989d1 r9 = rdx\n0x00404875 5e pop rsi\n0x00404876 4889e2 rdx = rsp\n0x00404879 4883e4f0 rsp &= 0xfffffffffffffff0\n\n\n30.11.0.3 asm.syntax: Select assembly syntax (intel, att, masm…)\ne asm.syntax=att\n0x00404870 31ed xor %ebp, %ebp\n0x00404872 4989d1 mov %rdx, %r9\n0x00404875 5e pop %rsi\n0x00404876 4889e2 mov %rsp, %rdx\n0x00404879 4883e4f0 and $0xfffffffffffffff0, %rsp\n\n\n30.11.0.4 asm.describe: Show opcode description\ne asm.describe=true\n0x00404870 xor ebp, ebp ; logical exclusive or\n0x00404872 mov r9, rdx ; moves data from src to dst\n0x00404875 pop rsi ; pops last element of stack and stores the result in argument\n0x00404876 mov rdx, rsp ; moves data from src to dst\n0x00404879 and rsp, -0xf ; binary and operation between src and dst, stores result on dst", + "title": "31  Visual Disassembly", + "section": "31.11 Examples", + "text": "31.11 Examples\n\n31.11.0.1 asm.arch: Change Architecture && asm.bits: Word size in bits at assembler\nYou can view the list of all arch using e asm.arch=?\ne asm.arch=dalvik\n0x00404870 31ed4989 cmp-long v237, v73, v137\n0x00404874 d15e4889 rsub-int v14, v5, 0x8948\n0x00404878 e24883e4 ushr-int/lit8 v72, v131, 0xe4\n0x0040487c f0505449c7c0 +invoke-object-init-range {}, method+18772 ;[0]\n0x00404882 90244100 add-int v36, v65, v0\ne asm.bits=16\n0000:4870 31ed xor bp, bp\n0000:4872 49 dec cx\n0000:4873 89d1 mov cx, dx\n0000:4875 5e pop si\n0000:4876 48 dec ax\n0000:4877 89e2 mov dx, sp\nThis latest operation can also be done using & in Visual mode.\n\n\n31.11.0.2 asm.pseudo: Enable pseudo syntax\ne asm.pseudo=true\n0x00404870 31ed ebp = 0\n0x00404872 4989d1 r9 = rdx\n0x00404875 5e pop rsi\n0x00404876 4889e2 rdx = rsp\n0x00404879 4883e4f0 rsp &= 0xfffffffffffffff0\n\n\n31.11.0.3 asm.syntax: Select assembly syntax (intel, att, masm…)\ne asm.syntax=att\n0x00404870 31ed xor %ebp, %ebp\n0x00404872 4989d1 mov %rdx, %r9\n0x00404875 5e pop %rsi\n0x00404876 4889e2 mov %rsp, %rdx\n0x00404879 4883e4f0 and $0xfffffffffffffff0, %rsp\n\n\n31.11.0.4 asm.describe: Show opcode description\ne asm.describe=true\n0x00404870 xor ebp, ebp ; logical exclusive or\n0x00404872 mov r9, rdx ; moves data from src to dst\n0x00404875 pop rsi ; pops last element of stack and stores the result in argument\n0x00404876 mov rdx, rsp ; moves data from src to dst\n0x00404879 and rsp, -0xf ; binary and operation between src and dst, stores result on dst", "crumbs": [ "Visual mode", - "30  Visual Disassembly" + "31  Visual Disassembly" ] }, { "objectID": "src/visual_mode/visual_assembler.html", "href": "src/visual_mode/visual_assembler.html", - "title": "31  Visual Assembler", + "title": "32  Visual Assembler", "section": "", "text": "You can use Visual Mode to assemble code (patch) using A. For example, let’s xor the EAX register instead of EBP register, here. To assemble, seek to the location you want to patch and press A.\n\n\n\nBefore\n\n\nNotice the preview of the disassembly and arrows. After assembling the instruction, you can see that the branch reference lines have been changed, and it is now pointing to the offset of the newly assembled jne instruction:\n\n\n\nAfter\n\n\nYou need to open the file in writing mode (rizin -w or oo+) in order to patch the file. You can also use the cache mode: e io.cache=true and wc?.\nRemember that patching files in debug mode only patches the memory, not the file.", "crumbs": [ "Visual mode", - "31  Visual Assembler" + "32  Visual Assembler" ] }, { "objectID": "src/visual_mode/visual_configuration_editor.html", "href": "src/visual_mode/visual_configuration_editor.html", - "title": "32  Visual Configuration Editor", + "title": "33  Visual Configuration Editor", "section": "", "text": "Ve or e in visual mode allows you to edit Rizin configuration visually. For example, if you want to change the assembly display just select asm in the list and choose your assembly display flavor.\n\n\n\nFirst Select asm\n\n\nExample switch to pseudo disassembly:\n\n\n\nPseudo disassembly disabled\n\n\n\n\n\nPseudo disassembly enabled", "crumbs": [ "Visual mode", - "32  Visual Configuration Editor" + "33  Visual Configuration Editor" ] }, { "objectID": "src/visual_mode/visual_panels.html", "href": "src/visual_mode/visual_panels.html", - "title": "33  Visual Panels", + "title": "34  Visual Panels", "section": "", - "text": "33.1 Concept\nVisual Panels is characterized by the following core functionalities:\nCUI met some useful GUI as the menu, that is Visual Panels.\nPanels can be accessed by using v or by using ! from the visual mode.", + "text": "34.1 Concept\nVisual Panels is characterized by the following core functionalities:\nCUI met some useful GUI as the menu, that is Visual Panels.\nPanels can be accessed by using v or by using ! from the visual mode.", "crumbs": [ "Visual mode", - "33  Visual Panels" + "34  Visual Panels" ] }, { "objectID": "src/visual_mode/visual_panels.html#concept", "href": "src/visual_mode/visual_panels.html#concept", - "title": "33  Visual Panels", + "title": "34  Visual Panels", "section": "", "text": "Split Screen\nDisplay multiple screens such as Symbols, Registers, Stack, as well as custom panels\nMenu will cover all those commonly used commands for you so that you don’t have to memorize any of them", "crumbs": [ "Visual mode", - "33  Visual Panels" + "34  Visual Panels" ] }, { "objectID": "src/visual_mode/visual_panels.html#overview", "href": "src/visual_mode/visual_panels.html#overview", - "title": "33  Visual Panels", - "section": "33.2 Overview", - "text": "33.2 Overview\n\n\n\nPanels Overview", + "title": "34  Visual Panels", + "section": "34.2 Overview", + "text": "34.2 Overview\n\n\n\nPanels Overview", "crumbs": [ "Visual mode", - "33  Visual Panels" + "34  Visual Panels" ] }, { "objectID": "src/visual_mode/visual_panels.html#commands", "href": "src/visual_mode/visual_panels.html#commands", - "title": "33  Visual Panels", - "section": "33.3 Commands", - "text": "33.3 Commands\n|Visual Ascii Art Panels:\n| | split the current panel vertically\n| - split the current panel horizontally\n| : run rizin command in prompt\n| ; add/remove comment\n| _ start the hud input mode\n| \\ show the user-friendly hud\n| ? show this help\n| . seek to PC or entrypoint\n| * show decompiler in the current panel\n| \" create a panel from the list and replace the current one\n| / highlight the keyword\n| ( toggle snow\n| & toggle cache\n| [1-9] follow jmp/call identified by shortcut (like ;[1])\n| ' ' (space) toggle graph / panels\n| tab go to the next panel\n| Enter start Zoom mode\n| a toggle auto update for decompiler\n| b browse symbols, flags, configurations, classes, ...\n| c toggle cursor\n| C toggle color\n| d define in the current address. Same as Vd\n| D show disassembly in the current panel\n| e change title and command of current panel\n| f set/add filter keywords\n| F remove all the filters\n| g go/seek to given offset\n| G go/seek to highlight\n| i insert hex\n| hjkl move around (left-down-up-right)\n| HJKL move around (left-down-up-right) by page\n| m select the menu panel\n| M open new custom frame\n| n/N seek next/prev function/flag/hit (scr.nkey)\n| p/P rotate panel layout\n| q quit, or close a tab\n| Q close all the tabs and quit\n| r toggle callhints/jmphints/leahints\n| R randomize color palette (ecr)\n| s/S step in / step over\n| t/T tab prompt / close a tab\n| u/U undo / redo seek\n| w start Window mode\n| V go to the graph mode\n| xX show xrefs/refs of current function from/to data/code\n| z swap current panel with the first one", + "title": "34  Visual Panels", + "section": "34.3 Commands", + "text": "34.3 Commands\n|Visual Ascii Art Panels:\n| | split the current panel vertically\n| - split the current panel horizontally\n| : run rizin command in prompt\n| ; add/remove comment\n| _ start the hud input mode\n| \\ show the user-friendly hud\n| ? show this help\n| . seek to PC or entrypoint\n| * show decompiler in the current panel\n| \" create a panel from the list and replace the current one\n| / highlight the keyword\n| ( toggle snow\n| & toggle cache\n| [1-9] follow jmp/call identified by shortcut (like ;[1])\n| ' ' (space) toggle graph / panels\n| tab go to the next panel\n| Enter start Zoom mode\n| a toggle auto update for decompiler\n| b browse symbols, flags, configurations, classes, ...\n| c toggle cursor\n| C toggle color\n| d define in the current address. Same as Vd\n| D show disassembly in the current panel\n| e change title and command of current panel\n| f set/add filter keywords\n| F remove all the filters\n| g go/seek to given offset\n| G go/seek to highlight\n| i insert hex\n| hjkl move around (left-down-up-right)\n| HJKL move around (left-down-up-right) by page\n| m select the menu panel\n| M open new custom frame\n| n/N seek next/prev function/flag/hit (scr.nkey)\n| p/P rotate panel layout\n| q quit, or close a tab\n| Q close all the tabs and quit\n| r toggle callhints/jmphints/leahints\n| R randomize color palette (ecr)\n| s/S step in / step over\n| t/T tab prompt / close a tab\n| u/U undo / redo seek\n| w start Window mode\n| V go to the graph mode\n| xX show xrefs/refs of current function from/to data/code\n| z swap current panel with the first one", "crumbs": [ "Visual mode", - "33  Visual Panels" + "34  Visual Panels" ] }, { "objectID": "src/visual_mode/visual_panels.html#basic-usage", "href": "src/visual_mode/visual_panels.html#basic-usage", - "title": "33  Visual Panels", - "section": "33.4 Basic Usage", - "text": "33.4 Basic Usage\nUse tab to move around the panels until you get to the targeted panel. Then, use hjkl, just like in vim, to scroll the panel you are currently on. Use S and s to step over/in, and all the panels should be updated dynamically while you are debugging. Either in the Registers or Stack panels, you can edit the values by inserting hex. This will be explained later. While hitting tab can help you to move between panels, it is highly recommended to use m to open the menu. As usual, you can use hjkl to move around the menu and will find tons of useful stuff there. You can also press \" to quickly browse through the different options View offers and change the contents of the selected panel.", + "title": "34  Visual Panels", + "section": "34.4 Basic Usage", + "text": "34.4 Basic Usage\nUse tab to move around the panels until you get to the targeted panel. Then, use hjkl, just like in vim, to scroll the panel you are currently on. Use S and s to step over/in, and all the panels should be updated dynamically while you are debugging. Either in the Registers or Stack panels, you can edit the values by inserting hex. This will be explained later. While hitting tab can help you to move between panels, it is highly recommended to use m to open the menu. As usual, you can use hjkl to move around the menu and will find tons of useful stuff there. You can also press \" to quickly browse through the different options View offers and change the contents of the selected panel.", "crumbs": [ "Visual mode", - "33  Visual Panels" + "34  Visual Panels" ] }, { "objectID": "src/visual_mode/visual_panels.html#split-screen", "href": "src/visual_mode/visual_panels.html#split-screen", - "title": "33  Visual Panels", - "section": "33.5 Split Screen", - "text": "33.5 Split Screen\n| is for the vertical and - is for the horizontal split. You can delete any panel by pressing X.\nSplit panels can be resized from Window Mode, which is accessed with w.", + "title": "34  Visual Panels", + "section": "34.5 Split Screen", + "text": "34.5 Split Screen\n| is for the vertical and - is for the horizontal split. You can delete any panel by pressing X.\nSplit panels can be resized from Window Mode, which is accessed with w.", "crumbs": [ "Visual mode", - "33  Visual Panels" + "34  Visual Panels" ] }, { "objectID": "src/visual_mode/visual_panels.html#window-mode-commands", "href": "src/visual_mode/visual_panels.html#window-mode-commands", - "title": "33  Visual Panels", - "section": "33.6 Window Mode Commands", - "text": "33.6 Window Mode Commands\n|Panels Window mode help:\n| ? show this help\n| ?? show the user-friendly hud\n| Enter start Zoom mode\n| c toggle cursor\n| hjkl move around (left-down-up-right)\n| JK resize panels vertically\n| HL resize panels horizontally\n| q quit Window mode", + "title": "34  Visual Panels", + "section": "34.6 Window Mode Commands", + "text": "34.6 Window Mode Commands\n|Panels Window mode help:\n| ? show this help\n| ?? show the user-friendly hud\n| Enter start Zoom mode\n| c toggle cursor\n| hjkl move around (left-down-up-right)\n| JK resize panels vertically\n| HL resize panels horizontally\n| q quit Window mode", "crumbs": [ "Visual mode", - "33  Visual Panels" + "34  Visual Panels" ] }, { "objectID": "src/visual_mode/visual_panels.html#edit-values", "href": "src/visual_mode/visual_panels.html#edit-values", - "title": "33  Visual Panels", - "section": "33.7 Edit Values", - "text": "33.7 Edit Values\nEither in the Register or Stack panel, you can edit the values. Use c to activate cursor mode, and you can move the cursor by pressing hjkl, as usual. Then, hit i, just like the insert mode of vim, to insert a value.", + "title": "34  Visual Panels", + "section": "34.7 Edit Values", + "text": "34.7 Edit Values\nEither in the Register or Stack panel, you can edit the values. Use c to activate cursor mode, and you can move the cursor by pressing hjkl, as usual. Then, hit i, just like the insert mode of vim, to insert a value.", "crumbs": [ "Visual mode", - "33  Visual Panels" + "34  Visual Panels" ] }, { "objectID": "src/visual_mode/visual_panels.html#tabs", "href": "src/visual_mode/visual_panels.html#tabs", - "title": "33  Visual Panels", - "section": "33.8 Tabs", - "text": "33.8 Tabs\nVisual Panels also offer tabs to quickly access multiple forms of information easily. Press t to enter Tab Mode. All the tabs numbers will be visible in the top right corner.\nBy default, you will have one tab, and you can press t to create a new tab with the same panels and T to create a new panel from scratch.\nFor traversing through the tabs, you can type in the tab number while in Tab Mode.\nAnd pressing - deletes the tab you are in.", + "title": "34  Visual Panels", + "section": "34.8 Tabs", + "text": "34.8 Tabs\nVisual Panels also offer tabs to quickly access multiple forms of information easily. Press t to enter Tab Mode. All the tabs numbers will be visible in the top right corner.\nBy default, you will have one tab, and you can press t to create a new tab with the same panels and T to create a new panel from scratch.\nFor traversing through the tabs, you can type in the tab number while in Tab Mode.\nAnd pressing - deletes the tab you are in.", "crumbs": [ "Visual mode", - "33  Visual Panels" + "34  Visual Panels" ] }, { "objectID": "src/visual_mode/visual_panels.html#saving-layouts", "href": "src/visual_mode/visual_panels.html#saving-layouts", - "title": "33  Visual Panels", - "section": "33.9 Saving layouts", - "text": "33.9 Saving layouts\nYou can save your custom layout of your visual panels either by picking the option ‘Save Layout’ from the File menu of the menu bar or by running:\nv= test\nWhere test is the name with which you’d like to save it.\nYou can open a saved layout by passing the name as the parameter to v:\nv test\nMore about that can be found under v?.", + "title": "34  Visual Panels", + "section": "34.9 Saving layouts", + "text": "34.9 Saving layouts\nYou can save your custom layout of your visual panels either by picking the option ‘Save Layout’ from the File menu of the menu bar or by running:\nv= test\nWhere test is the name with which you’d like to save it.\nYou can open a saved layout by passing the name as the parameter to v:\nv test\nMore about that can be found under v?.", "crumbs": [ "Visual mode", - "33  Visual Panels" + "34  Visual Panels" ] }, { "objectID": "src/search_bytes/intro.html", "href": "src/search_bytes/intro.html", - "title": "34  Searching for Bytes", + "title": "35  Searching for Bytes", "section": "", "text": "The Rizin search engine is based on work done by esteve, plus multiple features implemented on top of it. It supports multiple keyword searches, binary masks, and hexadecimal values. It automatically creates flags for search hit locations ease future referencing.\nSearch is initiated by / command.\n[0x00000000]> /?\nUsage: /[!bf] [arg] Search stuff (see 'e??search' for options)\n|Use io.va for searching in non virtual addressing spaces\n| / foo\\x00 search for string 'foo\\0'\n| /j foo\\x00 search for string 'foo\\0' (json output)\n| /! ff search for first occurrence not matching, command modifier\n| /!x 00 inverse hexa search (find first byte != 0x00)\n| /+ /bin/sh construct the string with chunks\n| // repeat last search\n| /a[?][1aoditfmsltf] jmp eax assemble opcode and search its bytes\n| /b search backwards, command modifier, followed by other command\n| /c[?][adr] search for crypto materials\n| /d 101112 search for a deltified sequence of bytes\n| /e /E.F/i match regular expression\n| /E esil-expr offset matching given esil expressions $$ = here\n| /f search forwards, (command modifier)\n| /F file [off] [sz] search contents of file with offset and size\n| /g[g] [from] find all graph paths A to B (/gg follow jumps, see search.count and analysis.depth)\n| /h[t] [hash] [len] find block matching this hash. See ph\n| /i foo search for string 'foo' ignoring case\n| /m[?][ebm] magicfile search for magic, filesystems or binary headers\n| /o [n] show offset of n instructions backward\n| /O [n] same as /o, but with a different fallback if analysis cannot be used\n| /p patternsize search for pattern of given size\n| /P patternsize search similar blocks\n| /s[*] [threshold] find sections by grouping blocks with similar entropy\n| /r[rwx][?] sym.printf analyze opcode reference an offset\n| /R [grepopcode] search for matching ROP gadgets, semicolon-separated\n| /v[1248] value look for an `cfg.bigendian` 32bit value\n| /V[1248] min max look for an `cfg.bigendian` 32bit value in range\n| /w foo search for wide string 'f\\0o\\0o\\0'\n| /wi foo search for wide string ignoring case 'f\\0o\\0o\\0'\n| /x ff..33 search for hex string ignoring some nibbles\n| /x ff0033 search for hex string\n| /x ff43:ffd0 search for hexpair with mask\n| /z min max search for strings of given size\n| /* [comment string] add multiline comment, end it with '*/'\nBecause everything is treated as a file in Rizin, it does not matter whether you search in a socket, a remote device, in process memory, or a file.\nNote that /* starts multiline comment. It’s not for searching. Type */ to end comment.", "crumbs": [ "Searching", - "34  Searching for Bytes" + "35  Searching for Bytes" ] }, { "objectID": "src/search_bytes/basic_searches.html", "href": "src/search_bytes/basic_searches.html", - "title": "35  Basic Search", + "title": "36  Basic Search", "section": "", "text": "A basic search for a plain text string in a file would be something like:\n$ rizin -q -c \"/ lib\" /bin/ls\nSearching 3 bytes from 0x00400000 to 0x0041ae08: 6c 69 62 \nhits: 9\n0x00400239 hit0_0 \"lib64/ld-linux-x86-64.so.2\"\n0x00400f19 hit0_1 \"libselinux.so.1\"\n0x00400fae hit0_2 \"librt.so.1\"\n0x00400fc7 hit0_3 \"libacl.so.1\"\n0x00401004 hit0_4 \"libc.so.6\"\n0x004013ce hit0_5 \"libc_start_main\"\n0x00416542 hit0_6 \"libs/\"\n0x00417160 hit0_7 \"lib/xstrtol.c\"\n0x00417578 hit0_8 \"lib\"\nAs can be seen from the output above, Rizin generates a “hit” flag for every entry found. You can then use the ps command to see the strings stored at the offsets marked by the flags in this group, and they will have names of the form hit0_<index>:\n[0x00404888]> / ls\n...\n[0x00404888]> ps @ hit0_0\nlseek\nYou can search for wide-char strings (e.g., Unicode letters) using the /w command:\n[0x00000000]> /w Hello\n0 results found.\nUsing Rizin, you can also automatically search for magic signatures in the file. This can be done using /m. The offset and the file format will be displayed after the search.\n[0x00000000]> /m\n-- 0 b1606\n0x00000000 1 JPEG image , EXIF standard\n0x0000000c 1 TIFF image data, big-endian\n0x000b1510 1 7-zip archive data, version 0.3\nTo perform a case-insensitive search for strings use /i:\n[0x0040488f]> /i Stallman\nSearching 8 bytes from 0x00400238 to 0x0040488f: 53 74 61 6c 6c 6d 61 6e\n[# ]hits: 004138 < 0x0040488f hits = 0\nIt is possible to specify hexadecimal escape sequences in the search string by prepending them with \\x:\n[0x00000000]> / \\x7FELF\nIf, instead, you are searching for a string of hexadecimal values, you’re probably better off using the /x command:\n[0x00000000]> /x 7F454C46\nOnce the search is done, the results are stored in the searches flag space.\n[0x00000000]> fs\n0 0 . strings\n1 0 . symbols\n2 6 . searches\n\n[0x00000000]> f\n0x00000135 512 hit0_0\n0x00000b71 512 hit0_1\n0x00000bad 512 hit0_2\n0x00000bdd 512 hit0_3\n0x00000bfb 512 hit0_4\n0x00000f2a 512 hit0_5\nTo remove “hit” flags after you do not need them anymore, use the f- hit* command.\nOften, during long search sessions, you will need to launch the latest search more than once. You can use the // command to repeat the last search.\n[0x00000f2a]> // ; repeat last search", "crumbs": [ "Searching", - "35  Basic Search" + "36  Basic Search" ] }, { "objectID": "src/search_bytes/configurating_the_search.html", "href": "src/search_bytes/configurating_the_search.html", - "title": "36  Configuring Search Options", + "title": "37  Configuring Search Options", "section": "", "text": "The Rizin search engine can be configured through several configuration variables, modifiable with the e command.\n[0x00000000]> ell cmd.hit\ncmd.hit = ; Run when a search hit is found\n\n[0x00000000]> ell search\nsearch.align = 0 ; Only catch aligned search hits\nsearch.case_sensitive = smart ; Set grep(~) as case smart/sensitive/insensitive [smart, sensitive, insensitive]\nsearch.chunk = 0 ; Chunk size for /+ (default size is asm.bits/8\nsearch.contiguous = true ; Accept contiguous/adjacent search hits\nsearch.distance = 0 ; Search string distance\nsearch.esilcombo = 8 ; Stop search after N consecutive hits\nsearch.flags = true ; All search results are flagged, otherwise only printed\nsearch.from = 0xffffffffffffffff ; Search start address\nsearch.in = io.maps ; Specify search boundaries [raw, block, bin.section, bin.sections, bin.sections.rwx, bin.sections.r, bin.sections.rw, bin.sections.rx, bin.sections.wx, bin.sections.x, io.map, io.maps, io.maps.rwx, io.maps.r, io.maps.rw, io.maps.rx, io.maps.wx, io.maps.x, dbg.stack, dbg.heap, dbg.map, dbg.maps, dbg.maps.rwx, dbg.maps.r, dbg.maps.rw, dbg.maps.rx, dbg.maps.wx, dbg.maps.x, analysis.fcn, analysis.bb]\nsearch.kwidx = 1 ; Store last search index count\nsearch.maxhits = 0 ; Maximum number of hits (0: no limit)\nsearch.overlap = false ; Look for overlapped search hits\nsearch.prefix = hit ; Prefix name in search hits label\nsearch.show = true ; Show search results\nsearch.to = 0xffffffffffffffff ; Search end address\nThe search.flags boolean variable instructs the search engine to flag hits so that they can be referenced later. If a currently running search is interrupted with Ctrl-C keyboard sequence, current search position is flagged with search_stop.", "crumbs": [ "Searching", - "36  Configuring Search Options" + "37  Configuring Search Options" ] }, { "objectID": "src/search_bytes/pattern_search.html", "href": "src/search_bytes/pattern_search.html", - "title": "37  Pattern Matching Search", + "title": "38  Pattern Matching Search", "section": "", "text": "The /p command allows you to apply repeated pattern searches on IO backend storage. It is possible to identify repeated byte sequences without explicitly specifying them. The only command’s parameter sets minimum detectable pattern length. Here is an example:\n[0x00000000]> /p 10\nThis command output will show different patterns found and how many times each of them is encountered.", "crumbs": [ "Searching", - "37  Pattern Matching Search" + "38  Pattern Matching Search" ] }, { "objectID": "src/search_bytes/automation.html", "href": "src/search_bytes/automation.html", - "title": "38  Search Automation", + "title": "39  Search Automation", "section": "", "text": "The cmd.hit configuration variable is used to define a Rizin command to be executed when a matching entry is found by the search engine. If you want to run several commands, separate them with ;. Alternatively, you can arrange them in a separate script, and then invoke it as a whole with . script-file-name command. For example:\n[0x00404888]> e cmd.hit=\"p8 8\"\n[0x00404888]> / lib\nSearching 3 bytes from 0x00400000 to 0x0041ae08: 6c 69 62\nhits: 9\n0x00400239 hit4_0 \"lib64/ld-linux-x86-64.so.2\"\n31ed4989d15e4889\n0x00400f19 hit4_1 \"libselinux.so.1\"\n31ed4989d15e4889\n0x00400fae hit4_2 \"librt.so.1\"\n31ed4989d15e4889\n0x00400fc7 hit4_3 \"libacl.so.1\"\n31ed4989d15e4889\n0x00401004 hit4_4 \"libc.so.6\"\n31ed4989d15e4889\n0x004013ce hit4_5 \"libc_start_main\"\n31ed4989d15e4889\n0x00416542 hit4_6 \"libs/\"\n31ed4989d15e4889\n0x00417160 hit4_7 \"lib/xstrtol.c\"\n31ed4989d15e4889\n0x00417578 hit4_8 \"lib\"\n31ed4989d15e4889", "crumbs": [ "Searching", - "38  Search Automation" + "39  Search Automation" ] }, { "objectID": "src/search_bytes/backward_search.html", "href": "src/search_bytes/backward_search.html", - "title": "39  Searching Backwards", + "title": "40  Searching Backwards", "section": "", "text": "Sometimes you want to find a keyword backwards. This is, before the current offset, to do this you can seek back and search forward by adding some search.from/to restrictions, or use the /b command.\n[0x100001200]> / nop\n0x100004b15 hit0_0 .STUWabcdefghiklmnopqrstuvwxbin/ls.\n0x100004f50 hit0_1 .STUWabcdefghiklmnopqrstuwx1] [file .\n[0x100001200]> /b nop\n[0x100001200]> s 0x100004f50p\n[0x100004f50]> /b nop\n0x100004b15 hit2_0 .STUWabcdefghiklmnopqrstuvwxbin/ls.\n[0x100004f50]>\nNote that /b is doing the same as /, but backward, so what if we want to use /x backward? We can use /bx, and the same goes for other search subcommands:\n[0x100001200]> /x 90\n0x100001a23 hit1_0 90\n0x10000248f hit1_1 90\n0x1000027b2 hit1_2 90\n0x100002b2e hit1_3 90\n0x1000032b8 hit1_4 90\n0x100003454 hit1_5 90\n0x100003468 hit1_6 90\n0x10000355b hit1_7 90\n0x100003647 hit1_8 90\n0x1000037ac hit1_9 90\n0x10000389c hit1_10 90\n0x100003c5c hit1_11 90\n\n[0x100001200]> /bx 90\n[0x100001200]> s 0x10000355b\n[0x10000355b]> /bx 90\n0x100003468 hit3_0 90\n0x100003454 hit3_1 90\n0x1000032b8 hit3_2 90\n0x100002b2e hit3_3 90\n0x1000027b2 hit3_4 90\n0x10000248f hit3_5 90\n0x100001a23 hit3_6 90\n[0x10000355b]>", "crumbs": [ "Searching", - "39  Searching Backwards" + "40  Searching Backwards" ] }, { "objectID": "src/search_bytes/search_in_assembly.html", "href": "src/search_bytes/search_in_assembly.html", - "title": "40  Assembler Search", + "title": "41  Assembler Search", "section": "", "text": "If you want to search for a certain assembler opcodes, you can use /a commands.\nThe command /ad/ jmp [esp] searches for the specified category of assembly mnemonic:\n[0x00404888]> /ad/ jmp qword [rdx]\nf hit_0 @ 0x0040e50d # 2: jmp qword [rdx]\nf hit_1 @ 0x00418dbb # 2: jmp qword [rdx]\nf hit_2 @ 0x00418fcb # 3: jmp qword [rdx]\nf hit_3 @ 0x004196ab # 6: jmp qword [rdx]\nf hit_4 @ 0x00419bf3 # 3: jmp qword [rdx]\nf hit_5 @ 0x00419c1b # 3: jmp qword [rdx]\nf hit_6 @ 0x00419c43 # 3: jmp qword [rdx]\nThe command /a jmp eax assembles a string to machine code, and then searches for the resulting bytes:\n[0x00404888]> /a jmp eax\nhits: 1\n0x004048e7 hit3_0 ffe00f1f8000000000b8", "crumbs": [ "Searching", - "40  Assembler Search" + "41  Assembler Search" ] }, { "objectID": "src/search_bytes/searching_aes_keys.html", "href": "src/search_bytes/searching_aes_keys.html", - "title": "41  Searching for AES Keys", + "title": "42  Searching for AES Keys", "section": "", "text": "Thanks to Victor Muñoz, Rizin now has support of the algorithm he developed, capable of finding expanded AES keys with /Ca command. It searches from current seek position up to the search.distance limit, or until end of file is reached. You can interrupt current search by pressing Ctrl-C. For example, to look for AES keys in physical memory of your system:\n$ sudo rizin /dev/mem\n[0x00000000]> /ca\n0 AES keys found\nIf you are simply looking for plaintext AES keys in your binary, /Ca will not find them, but you might want to search with is~AES instead if the programmer left those hints for you:\n[0x00000000]> /Ca\nSearching 0 byte in [0x100000-0x1f0000]\nhits: 0\nSearching 0 byte in [0x196e4-0x1b91c]\nhits: 0\nSearching 0 byte in [0x194b4-0x196e4]\nhits: 0\nSearching 0 byte in [0x8000-0x114b4]\nhits: 0\n[0x00000000]> is~AES\n010 0x000096d4 0x000196d4 GLOBAL OBJ 16 AES_KEY\nOther than that, AES keys might show up in different ways in the binary: encrypted, hidden by another encrypting routine, so there’s no absolute way other than understanding the binary being analyzed. For instance, p=e might give some hints if high(er) entropy sections are found trying to cover up a hardcoded secret. As an example on entropy searching, since rizin 3.2.0, there’s the possibility to delimit entropy sections for later use like so:\n[0x00000000]> b\n0x100\n[0x00000000]> b 4096\n[0x00000000]> /s\n0x00100000 - 0x00101000 ~ 5.556094\n0x014e2c88 - 0x014e3c88 ~ 0.000000\n0x01434374 - 0x01435374 ~ 6.332087\n0x01435374 - 0x0144c374 ~ 3.664636\n0x0144c374 - 0x0144d374 ~ 1.664368\n0x0144d374 - 0x0144f374 ~ 4.229199\n0x0144f374 - 0x01451374 ~ 2.000000\n(...)\n[0x00000000]> /s*\nf entropy_section_0 0x00001000 0x00100000\nf entropy_section_1 0x00001000 0x014e2c88\nf entropy_section_2 0x00001000 0x01434374\nf entropy_section_3 0x00017000 0x01435374\nf entropy_section_4 0x00001000 0x0144c374\nf entropy_section_5 0x00002000 0x0144d374\nf entropy_section_6 0x00002000 0x0144f374\nThe blocksize is increased to 4096 bytes from the default 100 bytes so that the entropy search /s can work on reasonably sized chunks for entropy analysis. The sections flags can be applied with the dot operator, ./s* and then looped through px 32 @@f:entropy*.\nMoreover, AES keys might be referenced from strings or pointed from the imports, for instance, so the / and other search-related commands can come in handy in this regard.", "crumbs": [ "Searching", - "41  Searching for AES Keys" + "42  Searching for AES Keys" ] }, { "objectID": "src/disassembling/intro.html", "href": "src/disassembling/intro.html", - "title": "42  Disassembling", + "title": "43  Disassembling", "section": "", "text": "Disassembling in Rizin is just a way to represent an array of bytes. It is handled as a special print mode within p command.\n$ rz-asm -L\nOr from inside Rizin:\n> e asm.arch=??\nThis was many years before capstone appeared. So Rizin was using udis86 and olly disassemblers, many gnu (from binutils).\nNowadays, the disassembler support is one of the basic features of Rizin. It now has many options, endianness, including target architecture flavor and disassembler variants, among other things.\nTo see the disassembly, use the pd command. It accepts a numeric argument to specify how many opcodes of current block you want to see. Most of the commands in Rizin consider the current block size as the default limit for data input. If you want to disassemble more bytes, set a new block size using the b command.\n[0x00000000]> b 100 ; set block size to 100\n[0x00000000]> pd ; disassemble 100 bytes\n[0x00000000]> pd 3 ; disassemble 3 opcodes\n[0x00000000]> pD 30 ; disassemble 30 bytes\nYou can also pass negative numbers as the numeric argument, if you want to disassemble something that lies before the current offset:\n[0x00005bc0]> pd -2\n 0x00005bb8 ret\n 0x00005bb9 nop dword [rax]\n[0x00005bc0]> pd 2\n ;-- entry.fini0:\n 0x00005bc0 endbr64\n 0x00005bc4 cmp byte [0x000232c8], 0\nThe pD command works like pd but accepts the number of input bytes as its argument, instead of the number of opcodes.\nYou can also get information about the pointer chains using the command pdp. This can be helpful while dealing with ROP chains.\nThe “pseudo” syntax may be somewhat easier for a human to understand than the default assembler notations. But it can become annoying if you read lots of code. To play with it:\n[0x00405e1c]> e asm.pseudo=true\n[0x00405e1c]> pd 3\n ; JMP XREF from 0x00405dfa (fcn.00404531)\n 0x00405e1c 488b9424a80. rdx = [rsp+0x2a8]\n 0x00405e24 64483314252. rdx ^= [fs:0x28]\n 0x00405e2d 4889d8 rax = rbx\n\n[0x00405e1c]> e asm.syntax=intel\n[0x00405e1c]> pd 3\n ; JMP XREF from 0x00405dfa (fcn.00404531)\n 0x00405e1c 488b9424a80. mov rdx, [rsp+0x2a8]\n 0x00405e24 64483314252. xor rdx, [fs:0x28]\n 0x00405e2d 4889d8 mov rax, rbx\n\n[0x00405e1c]> e asm.syntax=att\n[0x00405e1c]> pd 3\n ; JMP XREF from 0x00405dfa (fcn.00404531)\n 0x00405e1c 488b9424a80. mov 0x2a8(%rsp), %rdx\n 0x00405e24 64483314252. xor %fs:0x28, %rdx\n 0x00405e2d 4889d8 mov %rbx, %rax\nAnd as always, you can print the disassembly in JSON using pdj and get more information about the other associated commands by running pd?:\n[0x00000000]> pd?\nUsage: pd[?] # Print Disassembly\n| pd[jqt] [<n_instrs>] # Disassemble N instructions (can be negative)\n| pda[jq=] # Disassemble all possible opcodes (byte per byte)\n| pdb[jJ] # Disassemble basic block\n| pdC [<n_instrs>] # Prints the comments found in N instructions\n| pde[jqQ] [<n_instrs>] # Disassemble N instructions following execution flow from current PC\n| pdf[js] # Disassemble a function\n| pdJ[?] [<n_instrs>] # Disassemble N instructions as json containing the printed text\n| pdk # Disassemble all methods of a class\n| pdl[j] [<n_instrs>] # Disassemble N instructions and prints its sizes\n| pdp[jq] [<limit>] # Disassemble instructions and follows pointers to read ropchains\n| pdr[j.] # Disassemble recursively across the function graph\n| pdR[jq] # Disassemble recursively the block size bytes without analyzing functions\n| pds[fb] # Summarize N bytes or current block or a function (strings, calls, jumps, refs)\n| pdg[?] # Native Ghidra decompiler and Sleigh Disassembler plugin", "crumbs": [ "Disassembling", - "42  Disassembling" + "43  Disassembling" ] }, { "objectID": "src/disassembling/adding_metadata.html", "href": "src/disassembling/adding_metadata.html", - "title": "43  Adding Metadata to Disassembly", + "title": "44  Adding Metadata to Disassembly", "section": "", "text": "The typical work involved in reversing binary files makes powerful annotation capabilities essential. Rizin offers multiple ways to store and retrieve such metadata.\nBy following common basic UNIX principles, it is easy to write a small utility in a scripting language which uses objdump, otool or any other existing utility to obtain information from a binary and to import it into Rizin. For example, take a look at python-idb-based rz-ida.py which opens IDB files directly without IDA Pro installed. You can load the resulting file with the . (dot) command into the Rizin:\n[0x00000000]> . file.rz\nThe C command is used to manage comments and data conversions. You can define a range of program’s bytes to be interpreted as either code, binary data or string. It is also possible to execute external code at every specified flag location in order to fetch some metadata, such as a comment, from an external file or database.\nThere are many different metadata manipulation commands, here is the glimpse of all of them:\n[0x00404cc0]> C?\nUsage: C[?] # Code metadata (comments, format, hints, ..)\n| C[j*l] # List all meta information\n| C.[j*l] # Show all meta information at current address\n| C- # Remove meta information at current address\n| C-* # Remove all meta information\n| CC[?] # Manipulate the comments\n| CS[l-r?] # Manage metainformation spaces\n| Cf[l-?] # Manage the format string metainformation\n| Cd[l.-?] # Manage the raw data metainformation\n| Ch[l-?] # Manage the \"hidden\" mark metainformation\n| Cm[l-?] # Manage the \"magic\" mark metainformation\n| Cs[?] # Manipulate string metainformation\n| Ct[l-.?] # Manage the type metainformation\n| Cv[-elrs] # Add comments to the vars or arguments\nSimply to add the comment to a particular line/address you can use Ca command:\n[0x00000000]> CC 0x0000002 this guy seems legit\n[0x00000000]> pd 2\n0x00000000 0000 add [rax], al\n; this guy seems legit\n0x00000002 0000 add [rax], al\nThe C? family of commands lets you mark a range as one of several kinds of types. Three basic types are: code (disassembly is done using asm.arch), data (an array of data elements) or string. Use the Cs command to define a string, use the Cd command for defining an array of data elements, and use the Cf command to define more complex data structures like structs.\nAnnotating data types is most easily done in visual mode, using the “d” key, short for “data type change”. First, use the cursor to select a range of bytes (press c key to toggle cursor mode and use HJKL keys to expand selection), then press ‘d’ to get a menu of possible actions/types. For example, to mark the range as a string, use the ‘s’ option from the menu. You can achieve the same result from the shell using the Cs command:\n[0x00000000]> f string_foo @ 0x800\n[0x00000000]> Cs 10 @ string_foo\nThe Cf command is used to define a memory format string (the same syntax used by the pf command). Here’s an example:\n[0x7fd9f13ae630]> Cf 16 2xi foo bar\n[0x7fd9f13ae630]> pd\n;-- rip:\n0x7fd9f13ae630 format 2xi foo bar {\n0x7fd9f13ae630 [0] {\n foo : 0x7fd9f13ae630 = 0xe8e78948\n bar : 0x7fd9f13ae634 = 14696\n}\n0x7fd9f13ae638 [1] {\n foo : 0x7fd9f13ae638 = 0x8bc48949\n bar : 0x7fd9f13ae63c = 571928325\n}\n} 16\n0x7fd9f13ae633 e868390000 call 0x7fd9f13b1fa0\n0x7fd9f13ae638 4989c4 mov r12, rax\nThe [sz] argument to Cf is used to define how many bytes the struct should take up in the disassembly, and is completely independent of the size of the data structure defined by the format string. This may seem confusing, but has several uses. For example, you may want to see the formatted structure displayed in the disassembly, but still have those locations be visible as offsets and with raw bytes. Sometimes, you find large structures, but only identified a few fields, or only interested in specific fields. Then, you can tell Rizin to display only those fields, using the format string and using ‘skip’ fields, and also have the disassembly continue after the entire structure, by giving it full size using the sz argument.\nUsing Cf, it’s easy to define complex structures with simple one-liners. See pf? for more information. Remember that all these C commands can also be accessed from the visual mode by pressing the d (data conversion) key. Note that unlike t commands Cf doesn’t change analysis results. It is only a visual boon.\nSometimes just adding a single line of comments is not enough, in this case Rizin allows you to create a link for a particular text file. You can use it with CC, command or by pressing , key in the visual mode. This will open an $EDITOR to create a new file, or if filename does exist, just will create a link. It will be shown in the disassembly comments:\n[0x00003af7 11% 290 /bin/ls]> pd $r @ main+55 # 0x3af7\n│0x00003af7 call sym.imp.setlocale ;[1] ; ,(locale-help.txt) ; char *setlocale(int category, const char *locale)\n│0x00003afc lea rsi, str.usr_share_locale ; 0x179cc ; \"/usr/share/locale\"\n│0x00003b03 lea rdi, [0x000179b2] ; \"coreutils\"\n│0x00003b0a call sym.imp.bindtextdomain ;[2] ; char *bindtextdomain(char *domainname, char *dirname)\nNote ,(locale-help.txt) appeared in the comments, if we press , again in the visual mode, it will open the file. Using this mechanism we can create a long descriptions of some particular places in disassembly, link datasheets or related articles.", "crumbs": [ "Disassembling", - "43  Adding Metadata to Disassembly" + "44  Adding Metadata to Disassembly" ] }, { "objectID": "src/disassembling/esil.html", "href": "src/disassembling/esil.html", - "title": "44  ESIL", + "title": "45  ESIL", "section": "", - "text": "44.1 Using ESIL\nESIL stands for “Evaluable Strings Intermediate Language”. It aims to describe a Forth-like representation for every target CPU opcode semantics. ESIL representations can be evaluated (interpreted) in order to emulate individual instructions. Each command of an ESIL expression is separated by a comma. Its virtual machine can be described as this:\nAs we can see ESIL uses a stack-based interpreter similar to what is commonly used for calculators. You have two categories of inputs: values and operators. A value simply gets pushed on the stack, an operator then pops values (its arguments if you will) off the stack, performs its operation and pushes its results (if any) back on. We can think of ESIL as a post-fix notation of the operations we want to do.\nSo let’s see an example:\nCan you guess what this is? If we take this post-fix notation and transform it back to in-fix we get:\nWe can see that this corresponds to the x86 instruction push ebp! Isn’t that cool? The aim is to be able to express most of the common operations performed by CPUs, like binary arithmetic operations, memory loads and stores, processing syscalls. This way if we can transform the instructions to ESIL we can see what a program does while it is running even for the most cryptic architectures you definitely don’t have a device to debug on for.\nRizin’s visual mode is great to inspect the ESIL evaluations.\nThere are 3 environment variables that are important for watching what a program does:\nasm.emu tells Rizin if you want ESIL information to be displayed. If it is set to true, you will see comments appear to the right of your disassembly that tell you how the contents of registers and memory addresses are changed by the current instruction. For example, if you have an instruction that subtracts a value from a register it tells you what the value was before and what it becomes after. This is super useful so you don’t have to sit there yourself and track which value goes where.\nOne problem with this is that it is a lot of information to take in at once, and sometimes you simply don’t need it. Rizin has a nice compromise for this. That is what the emu.str variable is for (asm.emustr on <= 2.2). Instead of this super verbose output with every register value, this only adds really useful information to the output, e.g., strings that are found at addresses a program uses or whether a jump is likely to be taken or not.\nThe third important variable is asm.esil. This switches your disassembly to no longer show you the actual disassembled instructions, but instead now shows you corresponding ESIL expressions that describe what the instruction does. So if you want to take a look at how instructions are expressed in ESIL simply set “asm.esil” to true.\nIn visual mode you can also toggle this by simply typing O.", + "text": "45.1 Using ESIL\nESIL stands for “Evaluable Strings Intermediate Language”. It aims to describe a Forth-like representation for every target CPU opcode semantics. ESIL representations can be evaluated (interpreted) in order to emulate individual instructions. Each command of an ESIL expression is separated by a comma. Its virtual machine can be described as this:\nAs we can see ESIL uses a stack-based interpreter similar to what is commonly used for calculators. You have two categories of inputs: values and operators. A value simply gets pushed on the stack, an operator then pops values (its arguments if you will) off the stack, performs its operation and pushes its results (if any) back on. We can think of ESIL as a post-fix notation of the operations we want to do.\nSo let’s see an example:\nCan you guess what this is? If we take this post-fix notation and transform it back to in-fix we get:\nWe can see that this corresponds to the x86 instruction push ebp! Isn’t that cool? The aim is to be able to express most of the common operations performed by CPUs, like binary arithmetic operations, memory loads and stores, processing syscalls. This way if we can transform the instructions to ESIL we can see what a program does while it is running even for the most cryptic architectures you definitely don’t have a device to debug on for.\nRizin’s visual mode is great to inspect the ESIL evaluations.\nThere are 3 environment variables that are important for watching what a program does:\nasm.emu tells Rizin if you want ESIL information to be displayed. If it is set to true, you will see comments appear to the right of your disassembly that tell you how the contents of registers and memory addresses are changed by the current instruction. For example, if you have an instruction that subtracts a value from a register it tells you what the value was before and what it becomes after. This is super useful so you don’t have to sit there yourself and track which value goes where.\nOne problem with this is that it is a lot of information to take in at once, and sometimes you simply don’t need it. Rizin has a nice compromise for this. That is what the emu.str variable is for (asm.emustr on <= 2.2). Instead of this super verbose output with every register value, this only adds really useful information to the output, e.g., strings that are found at addresses a program uses or whether a jump is likely to be taken or not.\nThe third important variable is asm.esil. This switches your disassembly to no longer show you the actual disassembled instructions, but instead now shows you corresponding ESIL expressions that describe what the instruction does. So if you want to take a look at how instructions are expressed in ESIL simply set “asm.esil” to true.\nIn visual mode you can also toggle this by simply typing O.", "crumbs": [ "Disassembling", - "44  ESIL" + "45  ESIL" ] }, { "objectID": "src/disassembling/esil.html#using-esil", "href": "src/disassembling/esil.html#using-esil", - "title": "44  ESIL", + "title": "45  ESIL", "section": "", "text": "[0x00000000]> e emu.str=true\n\n\n\n[0x00000000]> e asm.esil=true", "crumbs": [ "Disassembling", - "44  ESIL" + "45  ESIL" ] }, { "objectID": "src/disassembling/esil.html#esil-commands", "href": "src/disassembling/esil.html#esil-commands", - "title": "44  ESIL", - "section": "44.2 ESIL Commands", - "text": "44.2 ESIL Commands\n\n“ae” : Evaluate ESIL expression.\n\n[0x00000000]> \"ae 1,1,+\"\n0x2\n[0x00000000]>\n\n“aes” : ESIL Step.\n\n[0x00000000]> aes\n[0x00000000]>10aes\n\n“aeso” : ESIL Step Over.\n\n[0x00000000]> aeso\n[0x00000000]>10aeso\n\n“aesu” : ESIL Step Until.\n\n[0x00001000]> aesu 0x1035\nADDR BREAK\n[0x00001019]>\n\n“ar” : Show/modify ESIL registry.\n\n[0x00001ec7]> ar r_00 = 0x1035\n[0x00001ec7]> ar r_00\n0x00001035\n[0x00001019]>\n\n44.2.1 ESIL Instruction Set\nHere is the complete instruction set used by the ESIL VM:\n\n\n\n\n\n\n\n\n\n\nESIL Opcode\nOperands\nName\nOperation\nexample\n\n\n\n\nTRAP\nsrc\nTrap\nTrap signal\n\n\n\n\\(** | src | Syscall | syscall | |\n| **\\)$\nsrc\nInstruction address\nGet address of current instructionstack=instruction address\n\n\n\n==\nsrc,dst\nCompare\nstack = (dst == src) ; update_eflags(dst - src)\n\n\n\n<\nsrc,dst\nSmaller (signed comparison)\nstack = (dst < src) ; update_eflags(dst - src)\n[0x0000000]> “ae 1,5,<” 0x0> “ae 5,5”0x0”\n\n\n<=\nsrc,dst\nSmaller or Equal (signed comparison)\nstack = (dst <= src) ; update_eflags(dst - src)\n[0x0000000]> “ae 1,5,<” 0x0> “ae 5,5”0x1”\n\n\n>\nsrc,dst\nBigger (signed comparison)\nstack = (dst > src) ; update_eflags(dst - src)\n> “ae 1,5,>”0x1> “ae 5,5,>”0x0\n\n\n>=\nsrc,dst\nBigger or Equal (signed comparison)\nstack = (dst >= src) ; update_eflags(dst - src)\n> “ae 1,5,>=”0x1> “ae 5,5,>=”0x1\n\n\n<<\nsrc,dst\nShift Left\nstack = dst << src\n> “ae 1,1,<<”0x2> “ae 2,1,<<”0x4\n\n\n>>\nsrc,dst\nShift Right\nstack = dst >> src\n> “ae 1,4,>>”0x2> “ae 2,4,>>”0x1\n\n\n<<<\nsrc,dst\nRotate Left\nstack=dst ROL src\n> “ae 31,1,<<<”0x80000000> “ae 32,1,<<<”0x1\n\n\n>>>\nsrc,dst\nRotate Right\nstack=dst ROR src\n> “ae 1,1,>>>”0x80000000> “ae 32,1,>>>”0x1\n\n\n&\nsrc,dst\nAND\nstack = dst & src\n> “ae 1,1,&”0x1> “ae 1,0,&”0x0> “ae 0,1,&”0x0> “ae 0,0,&”0x0\n\n\n|\nsrc,dst\nOR\nstack = dst | src\n> “ae 1,1,|”0x1> “ae 1,0,|”0x1> “ae 0,1,|”0x1> “ae 0,0,|”0x0\n\n\n^\nsrc,dst\nXOR\nstack = dst ^src\n> “ae 1,1,^”0x0> “ae 1,0,^”0x1> “ae 0,1,^”0x1> “ae 0,0,^”0x0\n\n\n+\nsrc,dst\nADD\nstack = dst + src\n> “ae 3,4,+”0x7> “ae 5,5,+”0xa\n\n\n-\nsrc,dst\nSUB\nstack = dst - src\n> “ae 3,4,-”0x1> “ae 5,5,-”0x0> “ae 4,3,-”0xffffffffffffffff\n\n\n*\nsrc,dst\nMUL\nstack = dst * src\n> “ae 3,4,*”0xc> “ae 5,5,*”0x19\n\n\n/\nsrc,dst\nDIV\nstack = dst / src\n> “ae 2,4,/”0x2> “ae 5,5,/”0x1> “ae 5,9,/”0x1\n\n\n%\nsrc,dst\nMOD\nstack = dst % src\n> “ae 2,4,%”0x0> “ae 5,5,%”0x0> “ae 5,9,%”0x4\n\n\n~\nbits,src\nSIGNEXT\nstack = src sign extended\n> “ae 8,0x80,~”0xffffffffffffff80\n\n\n~/\nsrc,dst\nSIGNED DIV\nstack = dst / src (signed)\n> “ae 2,-4,~/”0xfffffffffffffffe\n\n\n~%\nsrc,dst\nSIGNED MOD\nstack = dst % src (signed)\n> “ae 2,-5,~%”0xffffffffffffffff\n\n\n!\nsrc\nNEG\nstack = !!!src\n> “ae 1,!”0x0> “ae 4,!”0x0> “ae 0,!”0x1\n\n\n++\nsrc\nINC\nstack = src++\n> ar r_00=0;ar r_000x00000000> “ae r_00,++”0x1> ar r_000x00000000> “ae 1,++”0x2\n\n\n–\nsrc\nDEC\nstack = src–\n> ar r_00=5;ar r_000x00000005> “ae r_00,–”0x4> ar r_000x00000005> “ae 5,–”0x4\n\n\n=\nsrc,reg\nEQU\nreg = src\n> “ae 3,r_00,=”> aer r_000x00000003> “ae r_00,r_01,=”> aer r_010x00000003\n\n\n+=\nsrc,reg\nADD eq\nreg = reg + src\n> ar r_01=5;ar r_00=0;ar r_000x00000000> “ae r_01,r_00,+=”> ar r_000x00000005> “ae 5,r_00,+=”> ar r_000x0000000a\n\n\n-=\nsrc,reg\nSUB eq\nreg = reg - src\n> “ae r_01,r_00,-=”> ar r_000x00000004> “ae 3,r_00,-=”> ar r_000x00000001\n\n\n*=\nsrc,reg\nMUL eq\nreg = reg * src\n> ar r_01=3;ar r_00=5;ar r_000x00000005> “ae r_01,r_00,*=”> ar r_000x0000000f> “ae 2,r_00,*=”> ar r_000x0000001e\n\n\n/=\nsrc,reg\nDIV eq\nreg = reg / src\n> ar r_01=3;ar r_00=6;ar r_000x00000006> “ae r_01,r_00,/=”> ar r_000x00000002> “ae 1,r_00,/=”> ar r_000x00000002\n\n\n%=\nsrc,reg\nMOD eq\nreg = reg % src\n> ar r_01=3;ar r_00=7;ar r_00 0x00000007 > “ae r_01,r_00,%=” > ar r_00 0x00000001 > ar r_00=9;ar r_00 0x00000009 > “ae 5,r_00,%=” > ar r_00 0x00000004\n\n\n<<=\nsrc,reg\nShift Left eq\nreg = reg << src\n> ar r_00=1;ar r_01=1;ar r_010x00000001> “ae r_00,r_01,<<=”> ar r_010x00000002> “ae 2,r_01,<<=”> ar r_010x00000008\n\n\n>>=\nsrc,reg\nShift Right eq\nreg = reg << src\n> ar r_00=1;ar r_01=8;ar r_010x00000008> “ae r_00,r_01,>>=”> ar r_010x00000004> “ae 2,r_01,>>=”> ar r_010x00000001\n\n\n&=\nsrc,reg\nAND eq\nreg = reg & src\n> ar r_00=2;ar r_01=6;ar r_010x00000006> “ae r_00,r_01,&=”> ar r_010x00000002> “ae 2,r_01,&=”> ar r_010x00000002> “ae 1,r_01,&=”> ar r_010x00000000\n\n\n|=\nsrc,reg\nOR eq\nreg = reg | src\n> ar r_00=2;ar r_01=1;ar r_010x00000001> “ae r_00,r_01,|=”> ar r_010x00000003> “ae 4,r_01,|=”> ar r_010x00000007\n\n\n^=\nsrc,reg\nXOR eq\nreg = reg ^ src\n> ar r_00=2;ar r_01=0xab;ar r_010x000000ab> “ae r_00,r_01,^=”> ar r_010x000000a9> “ae 2,r_01,^=”> ar r_010x000000ab\n\n\n++=\nreg\nINC eq\nreg = reg + 1\n> ar r_00=4;ar r_000x00000004> “ae r_00,++=”> ar r_000x00000005\n\n\n–=\nreg\nDEC eq\nreg = reg - 1\n> ar r_00=4;ar r_000x00000004> “ae r_00,–=”> ar r_000x00000003\n\n\n!=\nreg\nNOT eq\nreg = !reg\n> ar r_00=4;ar r_000x00000004> “ae r_00,!=”> ar r_000x00000000> “ae r_00,!=”> ar r_000x00000001\n\n\n—\n—\n—\n—\n———————————————-\n\n\n=[]=[*]=[1]=[2]=[4]=[8]\nsrc,dst\npoke\n*dst=src\n> “ae 0xdeadbeef,0x10000,=[4],”> pxw 4@0x100000x00010000 0xdeadbeef ….> “ae 0x0,0x10000,=[4],”> pxw 4@0x100000x00010000 0x00000000\n\n\n[][*][1][2][4][8]\nsrc\npeek\nstack=*src\n> w test@0x10000> “ae 0x10000,[4],”0x74736574> ar r_00=0x10000> “ae r_00,[4],”0x74736574\n\n\n|=[]|=[1]|=[2]|=[4]|=[8]\nreg\nnombre\ncode\n> >\n\n\nSWAP\n\nSwap\nSwap two top elements\nSWAP\n\n\nPICK\nn\nPick\nPick nth element from the top of the stack\n2,PICK\n\n\nRPICK\nm\nReverse Pick\nPick nth element from the base of the stack\n0,RPICK\n\n\nDUP\n\nDuplicate\nDuplicate top element in stack\nDUP\n\n\nNUM\n\nNumeric\nIf top element is a reference (register name, label, etc), dereference it and push its real value\nNUM\n\n\nCLEAR\n\nClear\nClear stack\nCLEAR\n\n\nBREAK\n\nBreak\nStops ESIL emulation\nBREAK\n\n\nGOTO\nn\nGoto\nJumps to Nth ESIL word\nGOTO 5\n\n\nTODO\n\nTo Do\nStops execution (reason: ESIL expression not completed)\nTODO\n\n\n\n\n\n44.2.2 ESIL Flags\nESIL VM has an internal state flags that are read-only and can be used to export those values to the underlying target CPU flags. It is because the ESIL VM always calculates all flag changes, while target CPUs only update flags under certain conditions or at specific instructions.\nInternal flags are prefixed with $ character.\nz - zero flag, only set if the result of an operation is 0\nb - borrow, this requires to specify from which bit (example: $b4 - checks if borrow from bit 4)\nc - carry, same like above (example: $c7 - checks if carry from bit 7)\no - overflow\np - parity\nr - regsize ( asm.bits/8 )\ns - sign\nds - delay slot state\njt - jump target\njs - jump target set\n[0-9]* - Used to set flags and registers without having any side effects,\n i.e. setting esil_cur, esil_old and esil_lastsz.\n (example: \"$0,of,=\" to reset the overflow flag)", + "title": "45  ESIL", + "section": "45.2 ESIL Commands", + "text": "45.2 ESIL Commands\n\n“ae” : Evaluate ESIL expression.\n\n[0x00000000]> \"ae 1,1,+\"\n0x2\n[0x00000000]>\n\n“aes” : ESIL Step.\n\n[0x00000000]> aes\n[0x00000000]>10aes\n\n“aeso” : ESIL Step Over.\n\n[0x00000000]> aeso\n[0x00000000]>10aeso\n\n“aesu” : ESIL Step Until.\n\n[0x00001000]> aesu 0x1035\nADDR BREAK\n[0x00001019]>\n\n“ar” : Show/modify ESIL registry.\n\n[0x00001ec7]> ar r_00 = 0x1035\n[0x00001ec7]> ar r_00\n0x00001035\n[0x00001019]>\n\n45.2.1 ESIL Instruction Set\nHere is the complete instruction set used by the ESIL VM:\n\n\n\n\n\n\n\n\n\n\nESIL Opcode\nOperands\nName\nOperation\nexample\n\n\n\n\nTRAP\nsrc\nTrap\nTrap signal\n\n\n\n\\(** | src | Syscall | syscall | |\n| **\\)$\nsrc\nInstruction address\nGet address of current instructionstack=instruction address\n\n\n\n==\nsrc,dst\nCompare\nstack = (dst == src) ; update_eflags(dst - src)\n\n\n\n<\nsrc,dst\nSmaller (signed comparison)\nstack = (dst < src) ; update_eflags(dst - src)\n[0x0000000]> “ae 1,5,<” 0x0> “ae 5,5”0x0”\n\n\n<=\nsrc,dst\nSmaller or Equal (signed comparison)\nstack = (dst <= src) ; update_eflags(dst - src)\n[0x0000000]> “ae 1,5,<” 0x0> “ae 5,5”0x1”\n\n\n>\nsrc,dst\nBigger (signed comparison)\nstack = (dst > src) ; update_eflags(dst - src)\n> “ae 1,5,>”0x1> “ae 5,5,>”0x0\n\n\n>=\nsrc,dst\nBigger or Equal (signed comparison)\nstack = (dst >= src) ; update_eflags(dst - src)\n> “ae 1,5,>=”0x1> “ae 5,5,>=”0x1\n\n\n<<\nsrc,dst\nShift Left\nstack = dst << src\n> “ae 1,1,<<”0x2> “ae 2,1,<<”0x4\n\n\n>>\nsrc,dst\nShift Right\nstack = dst >> src\n> “ae 1,4,>>”0x2> “ae 2,4,>>”0x1\n\n\n<<<\nsrc,dst\nRotate Left\nstack=dst ROL src\n> “ae 31,1,<<<”0x80000000> “ae 32,1,<<<”0x1\n\n\n>>>\nsrc,dst\nRotate Right\nstack=dst ROR src\n> “ae 1,1,>>>”0x80000000> “ae 32,1,>>>”0x1\n\n\n&\nsrc,dst\nAND\nstack = dst & src\n> “ae 1,1,&”0x1> “ae 1,0,&”0x0> “ae 0,1,&”0x0> “ae 0,0,&”0x0\n\n\n|\nsrc,dst\nOR\nstack = dst | src\n> “ae 1,1,|”0x1> “ae 1,0,|”0x1> “ae 0,1,|”0x1> “ae 0,0,|”0x0\n\n\n^\nsrc,dst\nXOR\nstack = dst ^src\n> “ae 1,1,^”0x0> “ae 1,0,^”0x1> “ae 0,1,^”0x1> “ae 0,0,^”0x0\n\n\n+\nsrc,dst\nADD\nstack = dst + src\n> “ae 3,4,+”0x7> “ae 5,5,+”0xa\n\n\n-\nsrc,dst\nSUB\nstack = dst - src\n> “ae 3,4,-”0x1> “ae 5,5,-”0x0> “ae 4,3,-”0xffffffffffffffff\n\n\n*\nsrc,dst\nMUL\nstack = dst * src\n> “ae 3,4,*”0xc> “ae 5,5,*”0x19\n\n\n/\nsrc,dst\nDIV\nstack = dst / src\n> “ae 2,4,/”0x2> “ae 5,5,/”0x1> “ae 5,9,/”0x1\n\n\n%\nsrc,dst\nMOD\nstack = dst % src\n> “ae 2,4,%”0x0> “ae 5,5,%”0x0> “ae 5,9,%”0x4\n\n\n~\nbits,src\nSIGNEXT\nstack = src sign extended\n> “ae 8,0x80,~”0xffffffffffffff80\n\n\n~/\nsrc,dst\nSIGNED DIV\nstack = dst / src (signed)\n> “ae 2,-4,~/”0xfffffffffffffffe\n\n\n~%\nsrc,dst\nSIGNED MOD\nstack = dst % src (signed)\n> “ae 2,-5,~%”0xffffffffffffffff\n\n\n!\nsrc\nNEG\nstack = !!!src\n> “ae 1,!”0x0> “ae 4,!”0x0> “ae 0,!”0x1\n\n\n++\nsrc\nINC\nstack = src++\n> ar r_00=0;ar r_000x00000000> “ae r_00,++”0x1> ar r_000x00000000> “ae 1,++”0x2\n\n\n–\nsrc\nDEC\nstack = src–\n> ar r_00=5;ar r_000x00000005> “ae r_00,–”0x4> ar r_000x00000005> “ae 5,–”0x4\n\n\n=\nsrc,reg\nEQU\nreg = src\n> “ae 3,r_00,=”> aer r_000x00000003> “ae r_00,r_01,=”> aer r_010x00000003\n\n\n+=\nsrc,reg\nADD eq\nreg = reg + src\n> ar r_01=5;ar r_00=0;ar r_000x00000000> “ae r_01,r_00,+=”> ar r_000x00000005> “ae 5,r_00,+=”> ar r_000x0000000a\n\n\n-=\nsrc,reg\nSUB eq\nreg = reg - src\n> “ae r_01,r_00,-=”> ar r_000x00000004> “ae 3,r_00,-=”> ar r_000x00000001\n\n\n*=\nsrc,reg\nMUL eq\nreg = reg * src\n> ar r_01=3;ar r_00=5;ar r_000x00000005> “ae r_01,r_00,*=”> ar r_000x0000000f> “ae 2,r_00,*=”> ar r_000x0000001e\n\n\n/=\nsrc,reg\nDIV eq\nreg = reg / src\n> ar r_01=3;ar r_00=6;ar r_000x00000006> “ae r_01,r_00,/=”> ar r_000x00000002> “ae 1,r_00,/=”> ar r_000x00000002\n\n\n%=\nsrc,reg\nMOD eq\nreg = reg % src\n> ar r_01=3;ar r_00=7;ar r_00 0x00000007 > “ae r_01,r_00,%=” > ar r_00 0x00000001 > ar r_00=9;ar r_00 0x00000009 > “ae 5,r_00,%=” > ar r_00 0x00000004\n\n\n<<=\nsrc,reg\nShift Left eq\nreg = reg << src\n> ar r_00=1;ar r_01=1;ar r_010x00000001> “ae r_00,r_01,<<=”> ar r_010x00000002> “ae 2,r_01,<<=”> ar r_010x00000008\n\n\n>>=\nsrc,reg\nShift Right eq\nreg = reg << src\n> ar r_00=1;ar r_01=8;ar r_010x00000008> “ae r_00,r_01,>>=”> ar r_010x00000004> “ae 2,r_01,>>=”> ar r_010x00000001\n\n\n&=\nsrc,reg\nAND eq\nreg = reg & src\n> ar r_00=2;ar r_01=6;ar r_010x00000006> “ae r_00,r_01,&=”> ar r_010x00000002> “ae 2,r_01,&=”> ar r_010x00000002> “ae 1,r_01,&=”> ar r_010x00000000\n\n\n|=\nsrc,reg\nOR eq\nreg = reg | src\n> ar r_00=2;ar r_01=1;ar r_010x00000001> “ae r_00,r_01,|=”> ar r_010x00000003> “ae 4,r_01,|=”> ar r_010x00000007\n\n\n^=\nsrc,reg\nXOR eq\nreg = reg ^ src\n> ar r_00=2;ar r_01=0xab;ar r_010x000000ab> “ae r_00,r_01,^=”> ar r_010x000000a9> “ae 2,r_01,^=”> ar r_010x000000ab\n\n\n++=\nreg\nINC eq\nreg = reg + 1\n> ar r_00=4;ar r_000x00000004> “ae r_00,++=”> ar r_000x00000005\n\n\n–=\nreg\nDEC eq\nreg = reg - 1\n> ar r_00=4;ar r_000x00000004> “ae r_00,–=”> ar r_000x00000003\n\n\n!=\nreg\nNOT eq\nreg = !reg\n> ar r_00=4;ar r_000x00000004> “ae r_00,!=”> ar r_000x00000000> “ae r_00,!=”> ar r_000x00000001\n\n\n—\n—\n—\n—\n———————————————-\n\n\n=[]=[*]=[1]=[2]=[4]=[8]\nsrc,dst\npoke\n*dst=src\n> “ae 0xdeadbeef,0x10000,=[4],”> pxw 4@0x100000x00010000 0xdeadbeef ….> “ae 0x0,0x10000,=[4],”> pxw 4@0x100000x00010000 0x00000000\n\n\n[][*][1][2][4][8]\nsrc\npeek\nstack=*src\n> w test@0x10000> “ae 0x10000,[4],”0x74736574> ar r_00=0x10000> “ae r_00,[4],”0x74736574\n\n\n|=[]|=[1]|=[2]|=[4]|=[8]\nreg\nnombre\ncode\n> >\n\n\nSWAP\n\nSwap\nSwap two top elements\nSWAP\n\n\nPICK\nn\nPick\nPick nth element from the top of the stack\n2,PICK\n\n\nRPICK\nm\nReverse Pick\nPick nth element from the base of the stack\n0,RPICK\n\n\nDUP\n\nDuplicate\nDuplicate top element in stack\nDUP\n\n\nNUM\n\nNumeric\nIf top element is a reference (register name, label, etc), dereference it and push its real value\nNUM\n\n\nCLEAR\n\nClear\nClear stack\nCLEAR\n\n\nBREAK\n\nBreak\nStops ESIL emulation\nBREAK\n\n\nGOTO\nn\nGoto\nJumps to Nth ESIL word\nGOTO 5\n\n\nTODO\n\nTo Do\nStops execution (reason: ESIL expression not completed)\nTODO\n\n\n\n\n\n45.2.2 ESIL Flags\nESIL VM has an internal state flags that are read-only and can be used to export those values to the underlying target CPU flags. It is because the ESIL VM always calculates all flag changes, while target CPUs only update flags under certain conditions or at specific instructions.\nInternal flags are prefixed with $ character.\nz - zero flag, only set if the result of an operation is 0\nb - borrow, this requires to specify from which bit (example: $b4 - checks if borrow from bit 4)\nc - carry, same like above (example: $c7 - checks if carry from bit 7)\no - overflow\np - parity\nr - regsize ( asm.bits/8 )\ns - sign\nds - delay slot state\njt - jump target\njs - jump target set\n[0-9]* - Used to set flags and registers without having any side effects,\n i.e. setting esil_cur, esil_old and esil_lastsz.\n (example: \"$0,of,=\" to reset the overflow flag)", "crumbs": [ "Disassembling", - "44  ESIL" + "45  ESIL" ] }, { "objectID": "src/disassembling/esil.html#syntax-and-commands", "href": "src/disassembling/esil.html#syntax-and-commands", - "title": "44  ESIL", - "section": "44.3 Syntax and Commands", - "text": "44.3 Syntax and Commands\nA target opcode is translated into a comma separated list of ESIL expressions.\nxor eax, eax -> 0,eax,=,1,zf,=\nMemory access is defined by brackets operation:\nmov eax, [0x80480] -> 0x80480,[],eax,=\nDefault operand size is determined by size of operation destination.\nmovb $0, 0x80480 -> 0,0x80480,=[1]\nThe ? operator uses the value of its argument to decide whether to evaluate the expression in curly braces.\n\nIs the value zero? -> Skip it.\nIs the value non-zero? -> Evaluate it.\n\ncmp eax, 123 -> 123,eax,==,$z,zf,=\njz eax -> zf,?{,eax,eip,=,}\nIf you want to run several expressions under a conditional, put them in curly braces:\nzf,?{,eip,esp,=[],eax,eip,=,$r,esp,-=,}\nWhitespaces, newlines and other chars are ignored. So the first thing when processing a ESIL program is to remove spaces:\nesil = r_str_replace (esil, \" \", \"\", R_TRUE);\nSyscalls need special treatment. They are indicated by ‘$’ at the beginning of an expression. You can pass an optional numeric value to specify a number of syscall. An ESIL emulator must handle syscalls. See (r_esil_syscall).", + "title": "45  ESIL", + "section": "45.3 Syntax and Commands", + "text": "45.3 Syntax and Commands\nA target opcode is translated into a comma separated list of ESIL expressions.\nxor eax, eax -> 0,eax,=,1,zf,=\nMemory access is defined by brackets operation:\nmov eax, [0x80480] -> 0x80480,[],eax,=\nDefault operand size is determined by size of operation destination.\nmovb $0, 0x80480 -> 0,0x80480,=[1]\nThe ? operator uses the value of its argument to decide whether to evaluate the expression in curly braces.\n\nIs the value zero? -> Skip it.\nIs the value non-zero? -> Evaluate it.\n\ncmp eax, 123 -> 123,eax,==,$z,zf,=\njz eax -> zf,?{,eax,eip,=,}\nIf you want to run several expressions under a conditional, put them in curly braces:\nzf,?{,eip,esp,=[],eax,eip,=,$r,esp,-=,}\nWhitespaces, newlines and other chars are ignored. So the first thing when processing a ESIL program is to remove spaces:\nesil = r_str_replace (esil, \" \", \"\", R_TRUE);\nSyscalls need special treatment. They are indicated by ‘$’ at the beginning of an expression. You can pass an optional numeric value to specify a number of syscall. An ESIL emulator must handle syscalls. See (r_esil_syscall).", "crumbs": [ "Disassembling", - "44  ESIL" + "45  ESIL" ] }, { "objectID": "src/disassembling/esil.html#arguments-order-for-non-associative-operations", "href": "src/disassembling/esil.html#arguments-order-for-non-associative-operations", - "title": "44  ESIL", - "section": "44.4 Arguments Order for Non-associative Operations", - "text": "44.4 Arguments Order for Non-associative Operations\nAs discussed on IRC, the current implementation works like this:\na,b,- b - a\na,b,/= b /= a\nThis approach is more readable, but it is less stack-friendly.\n\n44.4.1 Special Instructions\nNOPs are represented as empty strings. As it was said previously, syscalls are marked by ‘\\(' command. For example,\n'0x80,\\)’. It delegates emulation from the ESIL machine to a callback which implements syscalls for a specific OS/kernel.\nTraps are implemented with the TRAP command. They are used to throw exceptions for invalid instructions, division by zero, memory read error, or any other needed by specific architectures.\n\n\n44.4.2 Quick Analysis\nHere is a list of some quick checks to retrieve information from an ESIL string. Relevant information will be probably found in the first expression of the list.\nindexOf('[') -> have memory references\nindexOf(\"=[\") -> write in memory\nindexOf(\"pc,=\") -> modifies program counter (branch, jump, call)\nindexOf(\"sp,=\") -> modifies the stack (what if we found sp+= or sp-=?)\nindexOf(\"=\") -> retrieve src and dst\nindexOf(\":\") -> unknown esil, raw opcode ahead\nindexOf(\"$\") -> accesses internal esil vm flags ex: $z\nindexOf(\"$\") -> syscall ex: 1,$\nindexOf(\"TRAP\") -> can trap\nindexOf('++') -> has iterator\nindexOf('--') -> count to zero\nindexOf(\"?{\") -> conditional\nequalsTo(\"\") -> empty string, aka nop (wrong, if we append pc+=x)\nCommon operations: * Check dstreg * Check srcreg * Get destination * Is jump * Is conditional * Evaluate * Is syscall\n\n\n44.4.3 CPU Flags\nCPU flags are usually defined as single bit registers in the RReg profile. They are sometimes found under the ‘flg’ register type.\n\n\n44.4.4 Variables\nProperties of the VM variables:\n\nThey have no predefined bit width. This way it should be easy to extend them to 128, 256 and 512 bits later, for MMX, SSE, AVX, Neon SIMD.\nThere can be unbound number of variables. It is done for SSA-form compatibility.\nRegister names have no specific syntax. They are just strings.\nNumbers can be specified in any base supported by RNum (dec, hex, oct, binary …).\nEach ESIL backend should have an associated RReg profile to describe the ESIL register specs.\n\n\n\n44.4.5 Bit Arrays\nWhat to do with them? What about bit arithmetic if use variables instead of registers?\n\n\n44.4.6 Arithmetic\n\nADD (“+”)\nMUL (“*”)\nSUB (“-”)\nDIV (“/”)\nMOD (“%”)\n\n\n\n44.4.7 Bit Arithmetic\n\nAND “&”\nOR “|”\nXOR “^”\nSHL “<<”\nSHR “>>”\nROL “<<<”\nROR “>>>”\nNEG “!”\n\n\n\n44.4.8 Floating Point Unit Support\nAt the moment of this writing, ESIL does not yet support FPU. But you can implement support for unsupported instructions using rz-pipe. Eventually we will get proper support for multimedia and floating point.\n\n\n44.4.9 Handling x86 REP Prefix in ESIL\nESIL specifies that the parsing control-flow commands must be uppercase. Bear in mind that some architectures have uppercase register names. The corresponding register profile should take care not to reuse any of the following:\n3,SKIP - skip N instructions. used to make relative forward GOTOs\n3,GOTO - goto instruction 3\nLOOP - alias for 0,GOTO\nBREAK - stop evaluating the expression\nSTACK - dump stack contents to screen\nCLEAR - clear stack\n\n44.4.9.1 Usage Example:\nrep cmpsb\ncx,!,?{,BREAK,},esi,[1],edi,[1],==,?{,BREAK,},esi,++,edi,++,cx,--,0,GOTO\n\n\n\n44.4.10 Unimplemented/Unhandled Instructions\nThose are expressed with the ‘TODO’ command. They act as a ‘BREAK’, but displays a warning message describing that an instruction is not implemented and will not be emulated. For example:\nfmulp ST(1), ST(0) => TODO,fmulp ST(1),ST(0)\n\n\n44.4.11 ESIL Disassembly Example:\n[0x1000010f8]> e asm.esil=true\n[0x1000010f8]> pd $r @ entry0\n0x1000010f8 55 8,rsp,-=,rbp,rsp,=[8]\n0x1000010f9 4889e5 rsp,rbp,=\n0x1000010fc 4883c768 104,rdi,+=\n0x100001100 4883c668 104,rsi,+=\n0x100001104 5d rsp,[8],rbp,=,8,rsp,+=\n0x100001105 e950350000 0x465a,rip,= ;[1]\n0x10000110a 55 8,rsp,-=,rbp,rsp,=[8]\n0x10000110b 4889e5 rsp,rbp,=\n0x10000110e 488d4668 rsi,104,+,rax,=\n0x100001112 488d7768 rdi,104,+,rsi,=\n0x100001116 4889c7 rax,rdi,=\n0x100001119 5d rsp,[8],rbp,=,8,rsp,+=\n0x10000111a e93b350000 0x465a,rip,= ;[1]\n0x10000111f 55 8,rsp,-=,rbp,rsp,=[8]\n0x100001120 4889e5 rsp,rbp,=\n0x100001123 488b4f60 rdi,96,+,[8],rcx,=\n0x100001127 4c8b4130 rcx,48,+,[8],r8,=\n0x10000112b 488b5660 rsi,96,+,[8],rdx,=\n0x10000112f b801000000 1,eax,=\n0x100001134 4c394230 rdx,48,+,[8],r8,==,cz,?=\n0x100001138 7f1a sf,of,!,^,zf,!,&,?{,0x1154,rip,=,} ;[2]\n0x10000113a 7d07 of,!,sf,^,?{,0x1143,rip,} ;[3]\n0x10000113c b8ffffffff 0xffffffff,eax,= ; 0xffffffff\n0x100001141 eb11 0x1154,rip,= ;[2]\n0x100001143 488b4938 rcx,56,+,[8],rcx,=\n0x100001147 48394a38 rdx,56,+,[8],rcx,==,cz,?=\n\n\n44.4.12 Introspection\nTo ease ESIL parsing we should have a way to express introspection expressions to extract the data that we want. For example, we may want to get the target address of a jump. The parser for ESIL expressions should offer an API to make it possible to extract information by analyzing the expressions easily.\n> ao~esil,opcode\nopcode: jmp 0x10000465a\nesil: 0x10000465a,rip,=\nWe need a way to retrieve the numeric value of ‘rip’. This is a very simple example, but there are more complex, like conditional ones. We need expressions to be able to get:\n\nopcode type\ndestination of a jump\ncondition depends on\nall regs modified (write)\nall regs accessed (read)\n\n\n\n44.4.13 API HOOKS\nIt is important for emulation to be able to setup hooks in the parser, so we can extend it to implement analysis without having to change it again and again. That is, every time an operation is about to be executed, a user hook is called. It can be used for example to determine if RIP is going to change, or if the instruction updates the stack. Later, we can split that callback into several ones to have an event-based analysis API that may be extended in JavaScript like this:\nesil.on('regset', function(){..\nesil.on('syscall', function(){esil.regset('rip'\nFor the API, see the functions hook_flag_read(), hook_execute() and hook_mem_read(). A callback should return true or 1 if you want to override the action that it takes. For example, to deny memory reads in a region, or voiding memory writes, effectively making it read-only. Return false or 0 if you want to trace ESIL expression parsing.\nOther operations require bindings to external functionalities to work. In this case, rz_ref and rz_io. This must be defined when initializing the ESIL VM.\n\nIo Get/Set\nOut ax, 44\n44,ax,:ou\nSelectors (cs,ds,gs…)\nMov eax, ds:[ebp+8]\nEbp,8,+,:ds,eax,=", + "title": "45  ESIL", + "section": "45.4 Arguments Order for Non-associative Operations", + "text": "45.4 Arguments Order for Non-associative Operations\nAs discussed on IRC, the current implementation works like this:\na,b,- b - a\na,b,/= b /= a\nThis approach is more readable, but it is less stack-friendly.\n\n45.4.1 Special Instructions\nNOPs are represented as empty strings. As it was said previously, syscalls are marked by ‘\\(' command. For example,\n'0x80,\\)’. It delegates emulation from the ESIL machine to a callback which implements syscalls for a specific OS/kernel.\nTraps are implemented with the TRAP command. They are used to throw exceptions for invalid instructions, division by zero, memory read error, or any other needed by specific architectures.\n\n\n45.4.2 Quick Analysis\nHere is a list of some quick checks to retrieve information from an ESIL string. Relevant information will be probably found in the first expression of the list.\nindexOf('[') -> have memory references\nindexOf(\"=[\") -> write in memory\nindexOf(\"pc,=\") -> modifies program counter (branch, jump, call)\nindexOf(\"sp,=\") -> modifies the stack (what if we found sp+= or sp-=?)\nindexOf(\"=\") -> retrieve src and dst\nindexOf(\":\") -> unknown esil, raw opcode ahead\nindexOf(\"$\") -> accesses internal esil vm flags ex: $z\nindexOf(\"$\") -> syscall ex: 1,$\nindexOf(\"TRAP\") -> can trap\nindexOf('++') -> has iterator\nindexOf('--') -> count to zero\nindexOf(\"?{\") -> conditional\nequalsTo(\"\") -> empty string, aka nop (wrong, if we append pc+=x)\nCommon operations: * Check dstreg * Check srcreg * Get destination * Is jump * Is conditional * Evaluate * Is syscall\n\n\n45.4.3 CPU Flags\nCPU flags are usually defined as single bit registers in the RReg profile. They are sometimes found under the ‘flg’ register type.\n\n\n45.4.4 Variables\nProperties of the VM variables:\n\nThey have no predefined bit width. This way it should be easy to extend them to 128, 256 and 512 bits later, for MMX, SSE, AVX, Neon SIMD.\nThere can be unbound number of variables. It is done for SSA-form compatibility.\nRegister names have no specific syntax. They are just strings.\nNumbers can be specified in any base supported by RNum (dec, hex, oct, binary …).\nEach ESIL backend should have an associated RReg profile to describe the ESIL register specs.\n\n\n\n45.4.5 Bit Arrays\nWhat to do with them? What about bit arithmetic if use variables instead of registers?\n\n\n45.4.6 Arithmetic\n\nADD (“+”)\nMUL (“*”)\nSUB (“-”)\nDIV (“/”)\nMOD (“%”)\n\n\n\n45.4.7 Bit Arithmetic\n\nAND “&”\nOR “|”\nXOR “^”\nSHL “<<”\nSHR “>>”\nROL “<<<”\nROR “>>>”\nNEG “!”\n\n\n\n45.4.8 Floating Point Unit Support\nAt the moment of this writing, ESIL does not yet support FPU. But you can implement support for unsupported instructions using rz-pipe. Eventually we will get proper support for multimedia and floating point.\n\n\n45.4.9 Handling x86 REP Prefix in ESIL\nESIL specifies that the parsing control-flow commands must be uppercase. Bear in mind that some architectures have uppercase register names. The corresponding register profile should take care not to reuse any of the following:\n3,SKIP - skip N instructions. used to make relative forward GOTOs\n3,GOTO - goto instruction 3\nLOOP - alias for 0,GOTO\nBREAK - stop evaluating the expression\nSTACK - dump stack contents to screen\nCLEAR - clear stack\n\n45.4.9.1 Usage Example:\nrep cmpsb\ncx,!,?{,BREAK,},esi,[1],edi,[1],==,?{,BREAK,},esi,++,edi,++,cx,--,0,GOTO\n\n\n\n45.4.10 Unimplemented/Unhandled Instructions\nThose are expressed with the ‘TODO’ command. They act as a ‘BREAK’, but displays a warning message describing that an instruction is not implemented and will not be emulated. For example:\nfmulp ST(1), ST(0) => TODO,fmulp ST(1),ST(0)\n\n\n45.4.11 ESIL Disassembly Example:\n[0x1000010f8]> e asm.esil=true\n[0x1000010f8]> pd $r @ entry0\n0x1000010f8 55 8,rsp,-=,rbp,rsp,=[8]\n0x1000010f9 4889e5 rsp,rbp,=\n0x1000010fc 4883c768 104,rdi,+=\n0x100001100 4883c668 104,rsi,+=\n0x100001104 5d rsp,[8],rbp,=,8,rsp,+=\n0x100001105 e950350000 0x465a,rip,= ;[1]\n0x10000110a 55 8,rsp,-=,rbp,rsp,=[8]\n0x10000110b 4889e5 rsp,rbp,=\n0x10000110e 488d4668 rsi,104,+,rax,=\n0x100001112 488d7768 rdi,104,+,rsi,=\n0x100001116 4889c7 rax,rdi,=\n0x100001119 5d rsp,[8],rbp,=,8,rsp,+=\n0x10000111a e93b350000 0x465a,rip,= ;[1]\n0x10000111f 55 8,rsp,-=,rbp,rsp,=[8]\n0x100001120 4889e5 rsp,rbp,=\n0x100001123 488b4f60 rdi,96,+,[8],rcx,=\n0x100001127 4c8b4130 rcx,48,+,[8],r8,=\n0x10000112b 488b5660 rsi,96,+,[8],rdx,=\n0x10000112f b801000000 1,eax,=\n0x100001134 4c394230 rdx,48,+,[8],r8,==,cz,?=\n0x100001138 7f1a sf,of,!,^,zf,!,&,?{,0x1154,rip,=,} ;[2]\n0x10000113a 7d07 of,!,sf,^,?{,0x1143,rip,} ;[3]\n0x10000113c b8ffffffff 0xffffffff,eax,= ; 0xffffffff\n0x100001141 eb11 0x1154,rip,= ;[2]\n0x100001143 488b4938 rcx,56,+,[8],rcx,=\n0x100001147 48394a38 rdx,56,+,[8],rcx,==,cz,?=\n\n\n45.4.12 Introspection\nTo ease ESIL parsing we should have a way to express introspection expressions to extract the data that we want. For example, we may want to get the target address of a jump. The parser for ESIL expressions should offer an API to make it possible to extract information by analyzing the expressions easily.\n> ao~esil,opcode\nopcode: jmp 0x10000465a\nesil: 0x10000465a,rip,=\nWe need a way to retrieve the numeric value of ‘rip’. This is a very simple example, but there are more complex, like conditional ones. We need expressions to be able to get:\n\nopcode type\ndestination of a jump\ncondition depends on\nall regs modified (write)\nall regs accessed (read)\n\n\n\n45.4.13 API HOOKS\nIt is important for emulation to be able to setup hooks in the parser, so we can extend it to implement analysis without having to change it again and again. That is, every time an operation is about to be executed, a user hook is called. It can be used for example to determine if RIP is going to change, or if the instruction updates the stack. Later, we can split that callback into several ones to have an event-based analysis API that may be extended in JavaScript like this:\nesil.on('regset', function(){..\nesil.on('syscall', function(){esil.regset('rip'\nFor the API, see the functions hook_flag_read(), hook_execute() and hook_mem_read(). A callback should return true or 1 if you want to override the action that it takes. For example, to deny memory reads in a region, or voiding memory writes, effectively making it read-only. Return false or 0 if you want to trace ESIL expression parsing.\nOther operations require bindings to external functionalities to work. In this case, rz_ref and rz_io. This must be defined when initializing the ESIL VM.\n\nIo Get/Set\nOut ax, 44\n44,ax,:ou\nSelectors (cs,ds,gs…)\nMov eax, ds:[ebp+8]\nEbp,8,+,:ds,eax,=", "crumbs": [ "Disassembling", - "44  ESIL" + "45  ESIL" ] }, { "objectID": "src/analysis/intro.html", "href": "src/analysis/intro.html", - "title": "45  Data and Code Analysis", + "title": "46  Data and Code Analysis", "section": "", "text": "Rizin has a very rich set of commands and configuration options to perform data and code analysis, to extract useful information from a binary, like pointers, string references, basic blocks, opcode data, jump targets, cross-references, and much more. These operations are handled by the a (analyze) command family:\n[0x00001100]> a?\nUsage: a [abdefFghoprxstc] [...]\n| a* same as afl*;ah*;ax*\n| aa[?] analyze all (fcns + bbs) (aa0 to avoid sub renaming)\n| a8 [hexpairs] analyze bytes\n| ab[?] [addr] analyze block\n| ad[?] analyze data trampoline (wip)\n| ad [from] [to] analyze data pointers to (from-to)\n| ae[?] [expr] analyze opcode eval expression (see ao)\n| af[?] analyze Functions\n| aF same as above, but using analysis.depth=1\n| ag[?] [options] draw graphs in various formats\n| ah[?] analysis hints (force opcode size, ...)\n| ai [addr] address information (show perms, stack, heap, ...)\n| aj same as a* but in json (aflj)\n| aL list all asm/analysis plugins (e asm.arch=?)\n| an [name] [@addr] show/rename/create whatever flag/function is used at addr\n| ao[?] [len] analyze Opcodes (or emulate it)\n| aO[?] [len] Analyze N instructions in M bytes\n| ap find prelude for current offset\n| ar[?] like 'dr' but for the esil vm. (registers)\n| as[?] [num] analyze syscall using dbg.reg\n| av[?] [.] show vtables\n| ax[?] manage refs/xrefs (see also afx?)\nIn fact, a namespace is one of the biggest in rizin tool and allows to control very different parts of the analysis:\n\nCode flow analysis\nData references analysis\nUsing loaded symbols\nManaging different type of graphs, like CFG and call graph\nManage variables\nManage types\nEmulation using ESIL VM\nOpcode introspection\nObjects information, like virtual tables", "crumbs": [ "Analysis", - "45  Data and Code Analysis" + "46  Data and Code Analysis" ] }, { "objectID": "src/analysis/code_analysis.html", "href": "src/analysis/code_analysis.html", - "title": "46  Code Analysis", + "title": "47  Code Analysis", "section": "", - "text": "46.1 Analyze functions\nCode analysis is a common technique used to extract information from assembly code.\nRizin has different code analysis techniques implemented in the core and available in different commands.\nAll features of Rizin are available from the library APIs as well as from commands. This gives you the ability to implement your own analysis loops using any programming language, even with Rizin one-liners, shell scripts, or analysis/core native plugins.\nThe analysis will show up the internal data structures to identify basic blocks, function trees and to extract opcode-level information.\nThe most common rizin analysis sequence utilizes is analyze all command (aa), which examines all symbols and entry-points. If the binary is stripped, using advance automated analysis aaa will be necessary; advanced analysis steps can be invoked manually with commands like aab, aar, or aac.\nLet’s analyse simple hello_world program:\nIn this example, we analyze the whole file (via aa) and then print disassembly of the main() function (via pdf). The aa command belongs to the family of auto analysis commands and performs only the most basic auto analysis steps. In Rizin there are many different types of auto analysis commands with a different analysis depth, including partial emulation: aa, aaa, aab, aaaa, … There is also a mapping of those commands to the rizin CLI options: rizin -A, rizin -AA, and so on.\nIt is common sense that completely automated analysis can produce non sequitur results, thus Rizin provides separate commands for the particular stages of the analysis allowing fine-grained control of the analysis process. Moreover, there is a treasure trove of configuration variables for controlling the analysis outcomes. You can find them via command el under analysis.* and emu.* variables namespaces.\nOne of the most important “basic” analysis commands is the set of af subcommands. af means “analyze function”. Using this command you can either allow automatic analysis of the particular function or perform a completely manual one.\nYou can use afl to list the functions found by the analysis.\nThere are a lot of useful commands under afl such as aflj (lists the function in JSON format; j is a common command suffix to provide JSON output), aflm (lists the functions in the syntax found in makefiles), or afll (lists all functions in verbose mode).\nThere’s also afl=, which displays ASCII-art bars with function ranges.\nYou can find the rest of them under afl?.\nSome of the most challenging tasks while performing a function analysis are merge, crop, and resize. As with other analysis commands, you have two modes: semi-automatic and manual. For the semi-automatic, you can use afm <function name> to merge the current function with the one specified by name as an argument, aff to readjust the function after analysis changes or function edits, afu <address> to do the resize and analysis of the current function until the specified address.\nApart from those semi-automatic ways to edit/analyze the function, you can handcraft it in the manual mode with af+ command and edit basic blocks of it using afb commands. Before changing the basic blocks of the function it is recommended to check the already presented ones:", + "text": "47.1 Analyze functions\nCode analysis is a common technique used to extract information from assembly code.\nRizin has different code analysis techniques implemented in the core and available in different commands.\nAll features of Rizin are available from the library APIs as well as from commands. This gives you the ability to implement your own analysis loops using any programming language, even with Rizin one-liners, shell scripts, or analysis/core native plugins.\nThe analysis will show up the internal data structures to identify basic blocks, function trees and to extract opcode-level information.\nThe most common rizin analysis sequence utilizes is analyze all command (aa), which examines all symbols and entry-points. If the binary is stripped, using advance automated analysis aaa will be necessary; advanced analysis steps can be invoked manually with commands like aab, aar, or aac.\nLet’s analyse simple hello_world program:\nIn this example, we analyze the whole file (via aa) and then print disassembly of the main() function (via pdf). The aa command belongs to the family of auto analysis commands and performs only the most basic auto analysis steps. In Rizin there are many different types of auto analysis commands with a different analysis depth, including partial emulation: aa, aaa, aab, aaaa, … There is also a mapping of those commands to the rizin CLI options: rizin -A, rizin -AA, and so on.\nIt is common sense that completely automated analysis can produce non sequitur results, thus Rizin provides separate commands for the particular stages of the analysis allowing fine-grained control of the analysis process. Moreover, there is a treasure trove of configuration variables for controlling the analysis outcomes. You can find them via command el under analysis.* and emu.* variables namespaces.\nOne of the most important “basic” analysis commands is the set of af subcommands. af means “analyze function”. Using this command you can either allow automatic analysis of the particular function or perform a completely manual one.\nYou can use afl to list the functions found by the analysis.\nThere are a lot of useful commands under afl such as aflj (lists the function in JSON format; j is a common command suffix to provide JSON output), aflm (lists the functions in the syntax found in makefiles), or afll (lists all functions in verbose mode).\nThere’s also afl=, which displays ASCII-art bars with function ranges.\nYou can find the rest of them under afl?.\nSome of the most challenging tasks while performing a function analysis are merge, crop, and resize. As with other analysis commands, you have two modes: semi-automatic and manual. For the semi-automatic, you can use afm <function name> to merge the current function with the one specified by name as an argument, aff to readjust the function after analysis changes or function edits, afu <address> to do the resize and analysis of the current function until the specified address.\nApart from those semi-automatic ways to edit/analyze the function, you can handcraft it in the manual mode with af+ command and edit basic blocks of it using afb commands. Before changing the basic blocks of the function it is recommended to check the already presented ones:", "crumbs": [ "Analysis", - "46  Code Analysis" + "47  Code Analysis" ] }, { "objectID": "src/analysis/code_analysis.html#analyze-functions", "href": "src/analysis/code_analysis.html#analyze-functions", - "title": "46  Code Analysis", + "title": "47  Code Analysis", "section": "", - "text": "[0x00001100]> af?\nUsage: af[?] # Analyze Functions commands\n| af [<name>] # Analyze functions recursively (honors `analysis.calls`)\n| afr [<name>] # Analyze functions recursively\n| af+ <name> [<type>] # Hand craft a function (requires `afb+`)\n| af- # Delete function\n| af-* # Delete all function analysis data\n| afj <tbl_addr> <elements> # Analyze function jumptable\n| afa # Analyze function arguments in a call\n| afal # Analyze function arguments in a call (honors `dbg.funcarg`)\n| afb[?] # Basic blocks commands\n| afB <bits> # Set asm.bits for the current function\n| afs[jb!r] # Function signatures commands\n| afo[j] # Show address of current function\n| afu <addr> # Resize and analyze function from current address until addr\n| afx[j] # List function references\n| afS <size> # Set stack frame size for function at current address\n| afv<?> # Manipulate arguments/variables in a function\n| afl[?] # List functions\n| afi[j*is] # Show/edit function information\n| afn[as] # Analyze function names\n| aft # Type matching analysis for the function in current seek\n| afM # Print functions map\n| afm <addr> # Merge two functions\n| afc[lor] # Calling convention\n| afd # Show function + delta for given offset\n\n\n\n\n\n\n[0x00003ac0]> afb\n0x00003ac0 0x00003b7f 01:001A 191 f 0x00003b7f\n0x00003b7f 0x00003b84 00:0000 5 j 0x00003b92 f 0x00003b84\n0x00003b84 0x00003b8d 00:0000 9 f 0x00003b8d\n0x00003b8d 0x00003b92 00:0000 5\n0x00003b92 0x00003ba8 01:0030 22 j 0x00003ba8\n0x00003ba8 0x00003bf9 00:0000 81\n\n46.1.1 Handcraft function\nBefore starting, let’s prepare a binary file first, for example:\nint code_block()\n{\n int result = 0;\n\n for(int i = 0; i < 10; ++i)\n result += 1;\n\n return result;\n}\nThen compile it with gcc -c example.c -m32 -O0 -fno-pie, we will get the object file example.o. Open it with rizin.\nSince we haven’t analyzed it yet, the pdf command will not print out the disassembly here:\n$ rizin example.o\n[0x08000034]> pdf\np: Cannot find function at 0x08000034\n[0x08000034]> pd\n ;-- section..text:\n ;-- .text:\n ;-- code_block:\n ;-- eip:\n 0x08000034 55 push ebp ; [01] -r-x section size 41 named .text\n 0x08000035 89e5 mov ebp, esp\n 0x08000037 83ec10 sub esp, 0x10\n 0x0800003a c745f8000000. mov dword [ebp - 8], 0\n 0x08000041 c745fc000000. mov dword [ebp - 4], 0\n ,=< 0x08000048 eb08 jmp 0x8000052\n .--> 0x0800004a 8345f801 add dword [ebp - 8], 1\n :| 0x0800004e 8345fc01 add dword [ebp - 4], 1\n :`-> 0x08000052 837dfc09 cmp dword [ebp - 4], 9\n `==< 0x08000056 7ef2 jle 0x800004a\n 0x08000058 8b45f8 mov eax, dword [ebp - 8]\n 0x0800005b c9 leave\n 0x0800005c c3 ret\n\nOur goal is to handcraft a function with the following structure\n\n\n\nanalyze_one\n\n\nCreate a function at 0x8000034 named code_block:\n[0x8000034]> af+ 0x8000034 code_block\nIn most cases, we use jump or call instructions as code block boundaries. So the range of first block is from 0x08000034 push ebp to 0x08000048 jmp 0x8000052. Use afb+ command to add it.\n[0x08000034]> afb+ code_block 0x8000034 0x800004a-0x8000034 0x8000052\nNote that the basic syntax of afb+ is afb+ function_address block_address block_size [jump] [fail]. The final instruction of this block points to a new address (jmp 0x8000052), thus we add the address of jump target (0x8000052) to reflect the jump info.\nThe next block (0x08000052 ~ 0x08000056) is more likely an if conditional statement which has two branches. It will jump to 0x800004a if less or equal, otherwise (the fail condition) jump to next instruction - 0x08000058:\n[0x08000034]> afb+ code_block 0x8000052 0x8000058-0x8000052 0x800004a 0x8000058\nFollow the control flow and create the remaining two blocks (two branches):\n[0x08000034]> afb+ code_block 0x800004a 0x8000052-0x800004a 0x8000052\n[0x08000034]> afb+ code_block 0x8000058 0x800005d-0x8000058\nCheck our work:\n[0x08000034]> afb\n0x08000034 0x0800004a 00:0000 22 j 0x08000052\n0x0800004a 0x08000052 00:0000 8 j 0x08000052\n0x08000052 0x08000058 00:0000 6 j 0x0800004a f 0x08000058\n0x08000058 0x0800005d 00:0000 5\n[0x08000034]> VV\n\n\n\nhandcraft_one\n\n\nThere are two very important commands for this: afc and afB. The latter is a must-know command for some platforms like ARM. It provides a way to change the “bitness” of a particular function by allowing to select between ARM and Thumb modes.\nafc on the other side, allows to manually specify function calling convention. You can find more information on its usage in calling_conventions.", + "text": "[0x00001100]> af?\nUsage: af[?] # Analyze Functions commands\n| af [<name>] # Analyze functions recursively (honors `analysis.calls`)\n| afr [<name>] # Analyze functions recursively\n| af+ <name> [<type>] # Hand craft a function (requires `afb+`)\n| af- # Delete function\n| af-* # Delete all function analysis data\n| afj <tbl_addr> <elements> # Analyze function jumptable\n| afa # Analyze function arguments in a call\n| afal # Analyze function arguments in a call (honors `dbg.funcarg`)\n| afb[?] # Basic blocks commands\n| afB <bits> # Set asm.bits for the current function\n| afs[jb!r] # Function signatures commands\n| afo[j] # Show address of current function\n| afu <addr> # Resize and analyze function from current address until addr\n| afx[j] # List function references\n| afS <size> # Set stack frame size for function at current address\n| afv<?> # Manipulate arguments/variables in a function\n| afl[?] # List functions\n| afi[j*is] # Show/edit function information\n| afn[as] # Analyze function names\n| aft # Type matching analysis for the function in current seek\n| afM # Print functions map\n| afm <addr> # Merge two functions\n| afc[lor] # Calling convention\n| afd # Show function + delta for given offset\n\n\n\n\n\n\n[0x00003ac0]> afb\n0x00003ac0 0x00003b7f 01:001A 191 f 0x00003b7f\n0x00003b7f 0x00003b84 00:0000 5 j 0x00003b92 f 0x00003b84\n0x00003b84 0x00003b8d 00:0000 9 f 0x00003b8d\n0x00003b8d 0x00003b92 00:0000 5\n0x00003b92 0x00003ba8 01:0030 22 j 0x00003ba8\n0x00003ba8 0x00003bf9 00:0000 81\n\n47.1.1 Handcraft function\nBefore starting, let’s prepare a binary file first, for example:\nint code_block()\n{\n int result = 0;\n\n for(int i = 0; i < 10; ++i)\n result += 1;\n\n return result;\n}\nThen compile it with gcc -c example.c -m32 -O0 -fno-pie, we will get the object file example.o. Open it with rizin.\nSince we haven’t analyzed it yet, the pdf command will not print out the disassembly here:\n$ rizin example.o\n[0x08000034]> pdf\np: Cannot find function at 0x08000034\n[0x08000034]> pd\n ;-- section..text:\n ;-- .text:\n ;-- code_block:\n ;-- eip:\n 0x08000034 55 push ebp ; [01] -r-x section size 41 named .text\n 0x08000035 89e5 mov ebp, esp\n 0x08000037 83ec10 sub esp, 0x10\n 0x0800003a c745f8000000. mov dword [ebp - 8], 0\n 0x08000041 c745fc000000. mov dword [ebp - 4], 0\n ,=< 0x08000048 eb08 jmp 0x8000052\n .--> 0x0800004a 8345f801 add dword [ebp - 8], 1\n :| 0x0800004e 8345fc01 add dword [ebp - 4], 1\n :`-> 0x08000052 837dfc09 cmp dword [ebp - 4], 9\n `==< 0x08000056 7ef2 jle 0x800004a\n 0x08000058 8b45f8 mov eax, dword [ebp - 8]\n 0x0800005b c9 leave\n 0x0800005c c3 ret\n\nOur goal is to handcraft a function with the following structure\n\n\n\nanalyze_one\n\n\nCreate a function at 0x8000034 named code_block:\n[0x8000034]> af+ 0x8000034 code_block\nIn most cases, we use jump or call instructions as code block boundaries. So the range of first block is from 0x08000034 push ebp to 0x08000048 jmp 0x8000052. Use afb+ command to add it.\n[0x08000034]> afb+ code_block 0x8000034 0x800004a-0x8000034 0x8000052\nNote that the basic syntax of afb+ is afb+ function_address block_address block_size [jump] [fail]. The final instruction of this block points to a new address (jmp 0x8000052), thus we add the address of jump target (0x8000052) to reflect the jump info.\nThe next block (0x08000052 ~ 0x08000056) is more likely an if conditional statement which has two branches. It will jump to 0x800004a if less or equal, otherwise (the fail condition) jump to next instruction - 0x08000058:\n[0x08000034]> afb+ code_block 0x8000052 0x8000058-0x8000052 0x800004a 0x8000058\nFollow the control flow and create the remaining two blocks (two branches):\n[0x08000034]> afb+ code_block 0x800004a 0x8000052-0x800004a 0x8000052\n[0x08000034]> afb+ code_block 0x8000058 0x800005d-0x8000058\nCheck our work:\n[0x08000034]> afb\n0x08000034 0x0800004a 00:0000 22 j 0x08000052\n0x0800004a 0x08000052 00:0000 8 j 0x08000052\n0x08000052 0x08000058 00:0000 6 j 0x0800004a f 0x08000058\n0x08000058 0x0800005d 00:0000 5\n[0x08000034]> VV\n\n\n\nhandcraft_one\n\n\nThere are two very important commands for this: afc and afB. The latter is a must-know command for some platforms like ARM. It provides a way to change the “bitness” of a particular function by allowing to select between ARM and Thumb modes.\nafc on the other side, allows to manually specify function calling convention. You can find more information on its usage in calling_conventions.", "crumbs": [ "Analysis", - "46  Code Analysis" + "47  Code Analysis" ] }, { "objectID": "src/analysis/code_analysis.html#recursive-analysis", "href": "src/analysis/code_analysis.html#recursive-analysis", - "title": "46  Code Analysis", - "section": "46.2 Recursive analysis", - "text": "46.2 Recursive analysis\nThere are 5 important program-wide half-automated analysis commands:\n\naab - perform basic-block analysis (“Nucleus” algorithm)\naac - analyze function calls from one (selected or current function)\naaf - analyze all function calls\naar - analyze data references\naad - analyze pointers to pointers references\n\nThose are only generic semi-automated reference searching algorithms. Rizin provides a wide choice of manual references’ creation of any kind. For this fine-grained control, you can use ax commands.\n[0x00001100]> ax?\nUsage: ax[?] # Cross references (xrefs)\n| ax <addr> # Add custom xref to addr from current seek\n| axc <addr> # Add generic code xref to addr from current seek\n| axC <addr> # Add call code xref to addr from current seek\n| axd <addr> # Add data xref to addr from current seek\n| axs <addr> # Add string xref to addr from current seek\n| axl[j*q] # List all xrefs\n| axt[j*q] # List xrefs to current seek\n| axf[j*q] # List xrefs from current seek\n| axtg # Display commands to generate graphs according to xrefs\n| ax- <addr> [<from>] # Delete xrefs to addr\n| ax-* # Delete all xrefs\n| axm <addr> # Copy xrefs pointing to addr to also point to curseek\n| axg[j*] # Show xrefs graph to reach function at current seek\n\nThe most commonly used ax commands are axt and axf, especially as a part of various rz-pipe scripts. Let’s say we see the string in the data or a code section and want to find all places it was referenced from, we should use axt:\n[0x0001783a]> pd 2\n;-- str.02x:\n; STRING XREF from 0x00005de0 (sub.strlen_d50)\n; CODE XREF from 0x00017838 (str.._s_s_s + 7)\n0x0001783a .string \"%%%02x\" ; len=7\n;-- str.src_ls.c:\n; STRING XREF from 0x0000541b (sub.free_b04)\n; STRING XREF from 0x0000543a (sub.__assert_fail_41f + 27)\n; STRING XREF from 0x00005459 (sub.__assert_fail_41f + 58)\n; STRING XREF from 0x00005f9e (sub._setjmp_e30)\n; CODE XREF from 0x0001783f (str.02x + 5)\n0x00017841 .string \"src/ls.c\" ; len=9\n[0x0001783a]> axt\nsub.strlen_d50 0x5de0 [STRING] lea rcx, str.02x\n(nofunc) 0x17838 [CODE] jae str.02x\nThere are also some useful commands under axt. Use axtg to generate rizin commands which will help you to create graphs according to the XREFs.\n[0x00001100]> s main\n[0x000011e9]> axtg\nagn 0x1118 \"entry0 + 24\"\nagn 0x11e9 \"main\"\nage 0x1118 0x11e9\nUse axt* to split the rizin commands and set flags on those corresponding XREFs.\nAlso under ax is axg, which finds the path between two points in the file by showing an XREFs graph to reach the location or function. For example:\n[0x000011e9]> axg\n- 0x000011e9 fcn 0x000011e9 main\n - 0x00001118 fcn 0x00001100 entry0\nUse axg* to generate rizin commands which will help you to create graphs using agn and age commands, according to the XREFs.\nApart from predefined algorithms to identify functions there is a way to specify a function prelude with a configuration option analysis.prelude. For example, like e analysis.prelude=0x554889e5 which means\npush rbp\nmov rbp, rsp\non x86_64 platform. It should be specified before any analysis commands.", + "title": "47  Code Analysis", + "section": "47.2 Recursive analysis", + "text": "47.2 Recursive analysis\nThere are 5 important program-wide half-automated analysis commands:\n\naab - perform basic-block analysis (“Nucleus” algorithm)\naac - analyze function calls from one (selected or current function)\naaf - analyze all function calls\naar - analyze data references\naad - analyze pointers to pointers references\n\nThose are only generic semi-automated reference searching algorithms. Rizin provides a wide choice of manual references’ creation of any kind. For this fine-grained control, you can use ax commands.\n[0x00001100]> ax?\nUsage: ax[?] # Cross references (xrefs)\n| ax <addr> # Add custom xref to addr from current seek\n| axc <addr> # Add generic code xref to addr from current seek\n| axC <addr> # Add call code xref to addr from current seek\n| axd <addr> # Add data xref to addr from current seek\n| axs <addr> # Add string xref to addr from current seek\n| axl[j*q] # List all xrefs\n| axt[j*q] # List xrefs to current seek\n| axf[j*q] # List xrefs from current seek\n| axtg # Display commands to generate graphs according to xrefs\n| ax- <addr> [<from>] # Delete xrefs to addr\n| ax-* # Delete all xrefs\n| axm <addr> # Copy xrefs pointing to addr to also point to curseek\n| axg[j*] # Show xrefs graph to reach function at current seek\n\nThe most commonly used ax commands are axt and axf, especially as a part of various rz-pipe scripts. Let’s say we see the string in the data or a code section and want to find all places it was referenced from, we should use axt:\n[0x0001783a]> pd 2\n;-- str.02x:\n; STRING XREF from 0x00005de0 (sub.strlen_d50)\n; CODE XREF from 0x00017838 (str.._s_s_s + 7)\n0x0001783a .string \"%%%02x\" ; len=7\n;-- str.src_ls.c:\n; STRING XREF from 0x0000541b (sub.free_b04)\n; STRING XREF from 0x0000543a (sub.__assert_fail_41f + 27)\n; STRING XREF from 0x00005459 (sub.__assert_fail_41f + 58)\n; STRING XREF from 0x00005f9e (sub._setjmp_e30)\n; CODE XREF from 0x0001783f (str.02x + 5)\n0x00017841 .string \"src/ls.c\" ; len=9\n[0x0001783a]> axt\nsub.strlen_d50 0x5de0 [STRING] lea rcx, str.02x\n(nofunc) 0x17838 [CODE] jae str.02x\nThere are also some useful commands under axt. Use axtg to generate rizin commands which will help you to create graphs according to the XREFs.\n[0x00001100]> s main\n[0x000011e9]> axtg\nagn 0x1118 \"entry0 + 24\"\nagn 0x11e9 \"main\"\nage 0x1118 0x11e9\nUse axt* to split the rizin commands and set flags on those corresponding XREFs.\nAlso under ax is axg, which finds the path between two points in the file by showing an XREFs graph to reach the location or function. For example:\n[0x000011e9]> axg\n- 0x000011e9 fcn 0x000011e9 main\n - 0x00001118 fcn 0x00001100 entry0\nUse axg* to generate rizin commands which will help you to create graphs using agn and age commands, according to the XREFs.\nApart from predefined algorithms to identify functions there is a way to specify a function prelude with a configuration option analysis.prelude. For example, like e analysis.prelude=0x554889e5 which means\npush rbp\nmov rbp, rsp\non x86_64 platform. It should be specified before any analysis commands.", "crumbs": [ "Analysis", - "46  Code Analysis" + "47  Code Analysis" ] }, { "objectID": "src/analysis/code_analysis.html#configuration", "href": "src/analysis/code_analysis.html#configuration", - "title": "46  Code Analysis", - "section": "46.3 Configuration", - "text": "46.3 Configuration\nRizin allows changing the behavior of almost any analysis stages or commands. There are different kinds of configuration options:\n\nFlow control\nBasic blocks control\nReferences control\nIO/Ranges\nJump tables analysis control\nPlatform/target-specific options\n\n\n46.3.1 Control flow configuration\nThe two most commonly used options for changing the behavior of control flow analysis in rizin are analysis.hasnext and analysis.jmp.after. The first one allows forcing rizin to continue the analysis after the end of the function, even if the next chunk of the code wasn’t called anywhere, thus analyzing all the available functions. The latter one allows forcing rizin to continue the analysis even after unconditional jumps.\nIn addition to those we can also set analysis.jmp.indir to follow the indirect jumps, continuing analysis; analysis.pushret to analyze push ...; ret sequence as a jump; analysis.nopskip to skip the NOP sequences at a function beginning.\nFor now, rizin also allows you to change the maximum basic block size with analysis.bb.maxsize option. The default value just works in most use cases, but it’s useful to increase that for example when dealing with obfuscated code. Beware that some of the basic block control options may disappear in the future in favor of more automated ways to set those.\nFor some unusual binaries or targets, there is an option analysis.noncode. Rizin doesn’t try to analyze data sections as a code by default. But in some cases - malware, packed binaries, binaries for embedded systems, it is often a case. Thus - this option.\n\n\n46.3.2 Reference control\nThe most crucial options that change the analysis results drastically. Sometimes some can be disabled to save time and memory when analyzing big binaries.\n\nanalysis.jmp.ref - to allow references creation for unconditional jumps\nanalysis.jmp.cref - same, but for conditional jumps\nanalysis.datarefs - to follow the data references in code\nanalysis.refstr - search for strings in data references\nanalysis.strings - search for strings and creating references\n\nNote that strings references control is disabled by default because it increases the analysis time.\n\n\n46.3.3 Analysis ranges\nThere are a few options for this:\n\nanalysis.limits - enables the range limits for analysis operations\nanalysis.from - starting address of the limit range\nanalysis.to - the corresponding end of the limit range\nanalysis.in - specify search boundaries for analysis. You can set it to io.maps, bin.sections, dbg.maps and many more. For example:\n\nTo analyze a specific memory map with analysis.from and analysis.to, set analysis.in=dbg.maps.\nTo analyze in the boundaries set by analysis.from and analysis.to, set analysis.in=range.\nTo analyze in the current mapped segment or section, you can put analysis.in=bin.segment or analysis.in=bin.section, respectively.\nTo analyze in the current memory map, specify analysis.in=dbg.map.\nTo analyze in the stack or heap, you can set analysis.in=dbg.stack or analysis.in=dbg.heap.\nTo analyze in the current function or basic block, you can specify analysis.in=analysis.fcn or analysis.in=analysis.bb.\n\n\nPlease see e analysis.in=?? for the complete list.\n\n\n46.3.4 Jump tables\nJump tables are one of the trickiest targets in binary reverse engineering. There are hundreds of different types, the end result depending on the compiler/linker and LTO stages of optimization. Thus, Rizin allows enabling some experimental jump tables detection algorithms using analysis.jmp.tbl option. Eventually, algorithms moved into the default analysis loops once they start to work on every supported platform/target/test-case. Two more options can affect the jump tables analysis results too:\n\nanalysis.jmp.indir - follow the indirect jumps, some jump tables rely on them\nanalysis.datarefs - follow the data references, some jump tables use those\n\n\n\n46.3.5 Platform specific controls\nThere are two common problems when analyzing embedded targets: ARM/Thumb detection and MIPS GP value. In the case of ARM binaries rizin supports some auto-detection of ARM/Thumb mode switches, but beware that it uses partial ESIL emulation, thus slowing the analysis process. If you do not like the results, particular functions’ mode can be overridden with afB command.\nThe MIPS GP problem is even trickier. It is basic knowledge that GP value can be different not only for the whole program but also for some functions. To partially solve that there are options analysis.gp and analysis.gpfixed. The first one sets the GP value for the whole program or particular function. The latter allows to “constantify” the GP value if some code is willing to change its value, always resetting it if the case. Those are heavily experimental and might be changed in the future in favor of more automated analysis.", + "title": "47  Code Analysis", + "section": "47.3 Configuration", + "text": "47.3 Configuration\nRizin allows changing the behavior of almost any analysis stages or commands. There are different kinds of configuration options:\n\nFlow control\nBasic blocks control\nReferences control\nIO/Ranges\nJump tables analysis control\nPlatform/target-specific options\n\n\n47.3.1 Control flow configuration\nThe two most commonly used options for changing the behavior of control flow analysis in rizin are analysis.hasnext and analysis.jmp.after. The first one allows forcing rizin to continue the analysis after the end of the function, even if the next chunk of the code wasn’t called anywhere, thus analyzing all the available functions. The latter one allows forcing rizin to continue the analysis even after unconditional jumps.\nIn addition to those we can also set analysis.jmp.indir to follow the indirect jumps, continuing analysis; analysis.pushret to analyze push ...; ret sequence as a jump; analysis.nopskip to skip the NOP sequences at a function beginning.\nFor now, rizin also allows you to change the maximum basic block size with analysis.bb.maxsize option. The default value just works in most use cases, but it’s useful to increase that for example when dealing with obfuscated code. Beware that some of the basic block control options may disappear in the future in favor of more automated ways to set those.\nFor some unusual binaries or targets, there is an option analysis.noncode. Rizin doesn’t try to analyze data sections as a code by default. But in some cases - malware, packed binaries, binaries for embedded systems, it is often a case. Thus - this option.\n\n\n47.3.2 Reference control\nThe most crucial options that change the analysis results drastically. Sometimes some can be disabled to save time and memory when analyzing big binaries.\n\nanalysis.jmp.ref - to allow references creation for unconditional jumps\nanalysis.jmp.cref - same, but for conditional jumps\nanalysis.datarefs - to follow the data references in code\nanalysis.refstr - search for strings in data references\nanalysis.strings - search for strings and creating references\n\nNote that strings references control is disabled by default because it increases the analysis time.\n\n\n47.3.3 Analysis ranges\nThere are a few options for this:\n\nanalysis.limits - enables the range limits for analysis operations\nanalysis.from - starting address of the limit range\nanalysis.to - the corresponding end of the limit range\nanalysis.in - specify search boundaries for analysis. You can set it to io.maps, bin.sections, dbg.maps and many more. For example:\n\nTo analyze a specific memory map with analysis.from and analysis.to, set analysis.in=dbg.maps.\nTo analyze in the boundaries set by analysis.from and analysis.to, set analysis.in=range.\nTo analyze in the current mapped segment or section, you can put analysis.in=bin.segment or analysis.in=bin.section, respectively.\nTo analyze in the current memory map, specify analysis.in=dbg.map.\nTo analyze in the stack or heap, you can set analysis.in=dbg.stack or analysis.in=dbg.heap.\nTo analyze in the current function or basic block, you can specify analysis.in=analysis.fcn or analysis.in=analysis.bb.\n\n\nPlease see e analysis.in=?? for the complete list.\n\n\n47.3.4 Jump tables\nJump tables are one of the trickiest targets in binary reverse engineering. There are hundreds of different types, the end result depending on the compiler/linker and LTO stages of optimization. Thus, Rizin allows enabling some experimental jump tables detection algorithms using analysis.jmp.tbl option. Eventually, algorithms moved into the default analysis loops once they start to work on every supported platform/target/test-case. Two more options can affect the jump tables analysis results too:\n\nanalysis.jmp.indir - follow the indirect jumps, some jump tables rely on them\nanalysis.datarefs - follow the data references, some jump tables use those\n\n\n\n47.3.5 Platform specific controls\nThere are two common problems when analyzing embedded targets: ARM/Thumb detection and MIPS GP value. In the case of ARM binaries rizin supports some auto-detection of ARM/Thumb mode switches, but beware that it uses partial ESIL emulation, thus slowing the analysis process. If you do not like the results, particular functions’ mode can be overridden with afB command.\nThe MIPS GP problem is even trickier. It is basic knowledge that GP value can be different not only for the whole program but also for some functions. To partially solve that there are options analysis.gp and analysis.gpfixed. The first one sets the GP value for the whole program or particular function. The latter allows to “constantify” the GP value if some code is willing to change its value, always resetting it if the case. Those are heavily experimental and might be changed in the future in favor of more automated analysis.", "crumbs": [ "Analysis", - "46  Code Analysis" + "47  Code Analysis" ] }, { "objectID": "src/analysis/code_analysis.html#visuals", "href": "src/analysis/code_analysis.html#visuals", - "title": "46  Code Analysis", - "section": "46.4 Visuals", - "text": "46.4 Visuals\nOne of the easiest ways to see and check the changes of the analysis commands and variables is to perform scrolling in a Vv special visual mode, allowing functions preview:\n\n\n\nvv\n\n\nWhen we want to check how analysis changes affect the result in the case of big functions, we can use minimap instead, allowing us to see a bigger flow graph on the same screen size. To get into the minimap mode type VV then press p twice:\n\n\n\nvv2\n\n\nThis mode allows you to see the disassembly of each node separately, just navigate between them using the Tab key.", + "title": "47  Code Analysis", + "section": "47.4 Visuals", + "text": "47.4 Visuals\nOne of the easiest ways to see and check the changes of the analysis commands and variables is to perform scrolling in a Vv special visual mode, allowing functions preview:\n\n\n\nvv\n\n\nWhen we want to check how analysis changes affect the result in the case of big functions, we can use minimap instead, allowing us to see a bigger flow graph on the same screen size. To get into the minimap mode type VV then press p twice:\n\n\n\nvv2\n\n\nThis mode allows you to see the disassembly of each node separately, just navigate between them using the Tab key.", "crumbs": [ "Analysis", - "46  Code Analysis" + "47  Code Analysis" ] }, { "objectID": "src/analysis/code_analysis.html#analysis-hints", "href": "src/analysis/code_analysis.html#analysis-hints", - "title": "46  Code Analysis", - "section": "46.5 Analysis hints", - "text": "46.5 Analysis hints\nIt is not an uncommon case that analysis results are not perfect even after you tried every single configuration option. This is where the “analysis hints” rizin mechanism comes in. It allows to override some basic opcode or meta-information properties, or even to rewrite the whole opcode string. These commands are located under ah namespace:\n[0x00001100]> ah?\nUsage: ah<?> # Analysis hints\n| ahl[j*] # List all analysis hints\n| ahl.[j*] # List analysis hints at current seek\n| ah- [<size>] # Delete analysis hints in region starting from current seek\n| ah-* # Delete all analysis hints\n| aha <arch> # Set arch hint\n| aha- # Delete arch hint\n| ahb <bits> # Set bits hint\n| ahb- # Delete bits hint\n| ahh # Set highlight hint\n| ahh- # Delete highlight hint\n| ahc <addr> # Set jump/call address hint\n| ahc- # Delete jump/call address hint\n| ahe <string> # Set ESIL string hint\n| ahe- # Delete ESIL string hint\n| ahd <opcode> # Set opcode hint\n| ahd- # Delete opcode hint\n| ahs <size> # Set opcode size hint\n| ahs- # Delete opcode size hint\n| ahf <addr> # Set fallback address hint\n| ahf- # Delete fallback address hint\n| ahF <size> # Set stackframe size hint\n| ahF- # Delete stackframe size hint\n| ahS <string> # Set asm syntax hint\n| ahS- # Delete asm syntax hint\n| ahp <pointer> # Set pointer hint\n| ahp- # Delete pointer hint\n| ahr <return> # Set function return value hint\n| ahr- # Delete function return value hint\n| ahv <value> # Set opcode value hint\n| ahv- # Delete opcode value hint\n| aho <string> # Set opcode type hint\n| aho- # Delete opcode type hint\n| ahi <type> [<nword>] # Set immediate base hint\n| ahi- # Delete immediate base hint\n| aht <struct.member> # Set structure offset hint\n| aht- # Delete structure offset hint\n| ahts <offset> # List all matching structure offsets\nOne of the most common cases is to set a particular numeric base for immediate:\n[0x00003d54]> ahi?\nUsage: ahi <type> [<nword>] # Set immediate base hint\n| ahi <base> # Set numeric <base> (2, 8, 10, 16)\n| ahi 10|d # Set base to signed decimal (10), sign bit should depend on receiver size\n| ahi 10u|du # Set base to unsigned decimal (11)\n| ahi b # Set base to binary (2)\n| ahi o # Set base to octal (8)\n| ahi h # Set base to hexadecimal (16)\n| ahi i # Set base to IP address (32)\n| ahi p # Set base to htons(port) (3)\n| ahi S # Set base to syscall (80)\n| ahi s # Set base to string (1)\n\nSet base of the N-th immediate (indexing starts from 0):\n| ahi 16 1 # Set base of the 1-st immediate to hexadecimal\n\n[0x00003d54]> pd 2\n0x00003d54 0583000000 add eax, 0x83\n0x00003d59 3d13010000 cmp eax, 0x113\n[0x00003d54]> ahi d\n[0x00003d54]> pd 2\n0x00003d54 0583000000 add eax, 131\n0x00003d59 3d13010000 cmp eax, 0x113\n[0x00003d54]> ahi b\n[0x00003d54]> pd 2\n0x00003d54 0583000000 add eax, 10000011b\n0x00003d59 3d13010000 cmp eax, 0x113\nIt is notable that some analysis stages or commands add the internal analysis hints, which can be checked with ah command:\n[0x00003d54]> ah\n 0x00003d54 - 0x00003d54 => immbase=2\n[0x00003d54]> ah*\n ahi 2 @ 0x3d54\nSometimes we need to override jump or call address, for example in case of tricky relocation, which is unknown for Rizin, thus we can change the value manually. The current analysis information about a particular opcode can be checked with ao command. We can use ahc command for performing such a change:\n[0x00003cee]> pd 2\n0x00003cee e83d080100 call sub.__errno_location_530\n0x00003cf3 85c0 test eax, eax\n[0x00003cee]> ao\naddress: 0x3cee\nopcode: call 0x14530\nmnemonic: call\nprefix: 0\nid: 56\nbytes: e83d080100\nrefptr: 0\nsize: 5\nsign: false\ntype: call\ncycles: 3\nesil: 83248,rip,8,rsp,-=,rsp,=[],rip,=\njump: 0x00014530\ndirection: exec\nfail: 0x00003cf3\nstack: null\nfamily: cpu\nstackop: null\n[0x00003cee]> ahc 0x5382\n[0x00003cee]> pd 2\n0x00003cee e83d080100 call sub.__errno_location_530\n0x00003cf3 85c0 test eax, eax\n[0x00003cee]> ao\naddress: 0x3cee\nopcode: call 0x14530\nmnemonic: call\nprefix: 0\nid: 56\nbytes: e83d080100\nrefptr: 0\nsize: 5\nsign: false\ntype: call\ncycles: 3\nesil: 83248,rip,8,rsp,-=,rsp,=[],rip,=\njump: 0x00005382\ndirection: exec\nfail: 0x00003cf3\nstack: null\nfamily: cpu\nstackop: null\n[0x00003cee]> ah\n 0x00003cee - 0x00003cee => jump: 0x5382\nAs you can see, despite the unchanged disassembly view the jump address in opcode was changed (jump option).\nIf anything of the previously described didn’t help, you can simply override shown disassembly with anything you like:\n[0x00003d54]> pd 2\n0x00003d54 0583000000 add eax, 10000011b\n0x00003d59 3d13010000 cmp eax, 0x113\n[0x00003d54]> \"ahd myopcode bla, foo\"\n[0x00003d54]> pd 2\n0x00003d54 myopcode bla, foo\n0x00003d55 830000 add dword [rax], 0", + "title": "47  Code Analysis", + "section": "47.5 Analysis hints", + "text": "47.5 Analysis hints\nIt is not an uncommon case that analysis results are not perfect even after you tried every single configuration option. This is where the “analysis hints” rizin mechanism comes in. It allows to override some basic opcode or meta-information properties, or even to rewrite the whole opcode string. These commands are located under ah namespace:\n[0x00001100]> ah?\nUsage: ah<?> # Analysis hints\n| ahl[j*] # List all analysis hints\n| ahl.[j*] # List analysis hints at current seek\n| ah- [<size>] # Delete analysis hints in region starting from current seek\n| ah-* # Delete all analysis hints\n| aha <arch> # Set arch hint\n| aha- # Delete arch hint\n| ahb <bits> # Set bits hint\n| ahb- # Delete bits hint\n| ahh # Set highlight hint\n| ahh- # Delete highlight hint\n| ahc <addr> # Set jump/call address hint\n| ahc- # Delete jump/call address hint\n| ahe <string> # Set ESIL string hint\n| ahe- # Delete ESIL string hint\n| ahd <opcode> # Set opcode hint\n| ahd- # Delete opcode hint\n| ahs <size> # Set opcode size hint\n| ahs- # Delete opcode size hint\n| ahf <addr> # Set fallback address hint\n| ahf- # Delete fallback address hint\n| ahF <size> # Set stackframe size hint\n| ahF- # Delete stackframe size hint\n| ahS <string> # Set asm syntax hint\n| ahS- # Delete asm syntax hint\n| ahp <pointer> # Set pointer hint\n| ahp- # Delete pointer hint\n| ahr <return> # Set function return value hint\n| ahr- # Delete function return value hint\n| ahv <value> # Set opcode value hint\n| ahv- # Delete opcode value hint\n| aho <string> # Set opcode type hint\n| aho- # Delete opcode type hint\n| ahi <type> [<nword>] # Set immediate base hint\n| ahi- # Delete immediate base hint\n| aht <struct.member> # Set structure offset hint\n| aht- # Delete structure offset hint\n| ahts <offset> # List all matching structure offsets\nOne of the most common cases is to set a particular numeric base for immediate:\n[0x00003d54]> ahi?\nUsage: ahi <type> [<nword>] # Set immediate base hint\n| ahi <base> # Set numeric <base> (2, 8, 10, 16)\n| ahi 10|d # Set base to signed decimal (10), sign bit should depend on receiver size\n| ahi 10u|du # Set base to unsigned decimal (11)\n| ahi b # Set base to binary (2)\n| ahi o # Set base to octal (8)\n| ahi h # Set base to hexadecimal (16)\n| ahi i # Set base to IP address (32)\n| ahi p # Set base to htons(port) (3)\n| ahi S # Set base to syscall (80)\n| ahi s # Set base to string (1)\n\nSet base of the N-th immediate (indexing starts from 0):\n| ahi 16 1 # Set base of the 1-st immediate to hexadecimal\n\n[0x00003d54]> pd 2\n0x00003d54 0583000000 add eax, 0x83\n0x00003d59 3d13010000 cmp eax, 0x113\n[0x00003d54]> ahi d\n[0x00003d54]> pd 2\n0x00003d54 0583000000 add eax, 131\n0x00003d59 3d13010000 cmp eax, 0x113\n[0x00003d54]> ahi b\n[0x00003d54]> pd 2\n0x00003d54 0583000000 add eax, 10000011b\n0x00003d59 3d13010000 cmp eax, 0x113\nIt is notable that some analysis stages or commands add the internal analysis hints, which can be checked with ah command:\n[0x00003d54]> ah\n 0x00003d54 - 0x00003d54 => immbase=2\n[0x00003d54]> ah*\n ahi 2 @ 0x3d54\nSometimes we need to override jump or call address, for example in case of tricky relocation, which is unknown for Rizin, thus we can change the value manually. The current analysis information about a particular opcode can be checked with ao command. We can use ahc command for performing such a change:\n[0x00003cee]> pd 2\n0x00003cee e83d080100 call sub.__errno_location_530\n0x00003cf3 85c0 test eax, eax\n[0x00003cee]> ao\naddress: 0x3cee\nopcode: call 0x14530\nmnemonic: call\nprefix: 0\nid: 56\nbytes: e83d080100\nrefptr: 0\nsize: 5\nsign: false\ntype: call\ncycles: 3\nesil: 83248,rip,8,rsp,-=,rsp,=[],rip,=\njump: 0x00014530\ndirection: exec\nfail: 0x00003cf3\nstack: null\nfamily: cpu\nstackop: null\n[0x00003cee]> ahc 0x5382\n[0x00003cee]> pd 2\n0x00003cee e83d080100 call sub.__errno_location_530\n0x00003cf3 85c0 test eax, eax\n[0x00003cee]> ao\naddress: 0x3cee\nopcode: call 0x14530\nmnemonic: call\nprefix: 0\nid: 56\nbytes: e83d080100\nrefptr: 0\nsize: 5\nsign: false\ntype: call\ncycles: 3\nesil: 83248,rip,8,rsp,-=,rsp,=[],rip,=\njump: 0x00005382\ndirection: exec\nfail: 0x00003cf3\nstack: null\nfamily: cpu\nstackop: null\n[0x00003cee]> ah\n 0x00003cee - 0x00003cee => jump: 0x5382\nAs you can see, despite the unchanged disassembly view the jump address in opcode was changed (jump option).\nIf anything of the previously described didn’t help, you can simply override shown disassembly with anything you like:\n[0x00003d54]> pd 2\n0x00003d54 0583000000 add eax, 10000011b\n0x00003d59 3d13010000 cmp eax, 0x113\n[0x00003d54]> \"ahd myopcode bla, foo\"\n[0x00003d54]> pd 2\n0x00003d54 myopcode bla, foo\n0x00003d55 830000 add dword [rax], 0", "crumbs": [ "Analysis", - "46  Code Analysis" + "47  Code Analysis" ] }, { "objectID": "src/analysis/variables.html", "href": "src/analysis/variables.html", - "title": "47  Managing variables", + "title": "48  Managing variables", "section": "", - "text": "47.1 Type inference\nRizin allows managing local variables, no matter their location, stack or registers. The variables’ auto analysis is enabled by default but can be disabled with analysis.vars configuration option.\nThe main variables commands are located in afv namespace:\nafvr and afvs commands are uniform but allow manipulation of register-based arguments and variables, and SP-based arguments and variables respectively. If we check the help for afvr we will get the way two others commands works too:\nLike many other things variables detection is performed by Rizin automatically, but results can be changed with those arguments/variables control commands. This kind of analysis relies heavily on preloaded function prototypes and the calling-convention, thus loading symbols can improve it. Moreover, after changing something we can rerun variables analysis with afva command. Quite often variables analysis is accompanied by types analysis, see afta command.\nThe most important aspect of reverse engineering - naming things. Of course, you can rename a variable too, affecting all places it was referenced. This can be achieved with afvn for any type of argument or variable. Or you can simply remove the variable or argument with afv- command.\nAs mentioned before the analysis loop relies heavily on types information while performing variables analysis stages. Let’s see all variables that found by Rizin:\nunknown_t means an “undefined” default type for variable whose exact type can’t be inferred. Thus comes very important command - afvt, which allows you to change the type of variable:\nLess commonly used feature, which is still under heavy development - distinction between variables being read and written. You can list those being read with afvR command and those being written with afvW command. Both commands provide a list of the places those operations are performed:\nThe type inference for local variables and arguments is well integrated with the command aft.\nLet’s see an example of this with a simple hello_world binary:\nAfter applying aft:\nIt also extracts type information from format strings like printf (\"fmt : %s , %u , %d\", ...), the format specifications are extracted from analysis/d/spec.sdb\nYou could create a new profile for specifying a set of format chars depending on different libraries/operating systems/programming languages like this:\nThen change your default specification to a newly created one using this config variable e analysis.spec=win\nFor more information about primitive and user-defined types support in Rizin refer to types chapter.", + "text": "48.1 Type inference\nRizin allows managing local variables, no matter their location, stack or registers. The variables’ auto analysis is enabled by default but can be disabled with analysis.vars configuration option.\nThe main variables commands are located in afv namespace:\nafvr and afvs commands are uniform but allow manipulation of register-based arguments and variables, and SP-based arguments and variables respectively. If we check the help for afvr we will get the way two others commands works too:\nLike many other things variables detection is performed by Rizin automatically, but results can be changed with those arguments/variables control commands. This kind of analysis relies heavily on preloaded function prototypes and the calling-convention, thus loading symbols can improve it. Moreover, after changing something we can rerun variables analysis with afva command. Quite often variables analysis is accompanied by types analysis, see afta command.\nThe most important aspect of reverse engineering - naming things. Of course, you can rename a variable too, affecting all places it was referenced. This can be achieved with afvn for any type of argument or variable. Or you can simply remove the variable or argument with afv- command.\nAs mentioned before the analysis loop relies heavily on types information while performing variables analysis stages. Let’s see all variables that found by Rizin:\nunknown_t means an “undefined” default type for variable whose exact type can’t be inferred. Thus comes very important command - afvt, which allows you to change the type of variable:\nLess commonly used feature, which is still under heavy development - distinction between variables being read and written. You can list those being read with afvR command and those being written with afvW command. Both commands provide a list of the places those operations are performed:\nThe type inference for local variables and arguments is well integrated with the command aft.\nLet’s see an example of this with a simple hello_world binary:\nAfter applying aft:\nIt also extracts type information from format strings like printf (\"fmt : %s , %u , %d\", ...), the format specifications are extracted from analysis/d/spec.sdb\nYou could create a new profile for specifying a set of format chars depending on different libraries/operating systems/programming languages like this:\nThen change your default specification to a newly created one using this config variable e analysis.spec=win\nFor more information about primitive and user-defined types support in Rizin refer to types chapter.", "crumbs": [ "Analysis", - "47  Managing variables" + "48  Managing variables" ] }, { "objectID": "src/analysis/variables.html#type-inference", "href": "src/analysis/variables.html#type-inference", - "title": "47  Managing variables", + "title": "48  Managing variables", "section": "", "text": "[0x00001100]> aa\n[x] Analyze all flags starting with sym. and entry0 (aa)\n\n[0x00001100]> s main\n\n[0x000011e9]> pdf\n ; DATA XREF from entry0 @ 0x1118\n/ int main(int argc, char **argv, char **envp);\n| ; arg int argc @ rdi\n| ; arg char **argv @ rsi\n| ; var int64_t var_48h @ stack - 0x48\n| ; var int64_t var_3ch @ stack - 0x3c\n| ; var int64_t var_30h @ stack - 0x30\n| ; var int64_t var_28h @ stack - 0x28\n| ; var int64_t var_20h @ stack - 0x20\n| ; var int64_t var_18h @ stack - 0x18\n| ; var int64_t var_10h @ stack - 0x10\n| 0x000011e9 endbr64\n| 0x000011ed push rbp\n| 0x000011ee mov rbp, rsp\n| 0x000011f1 sub rsp, 0x40\n| 0x000011f5 mov dword [var_3ch], edi ; argc\n| 0x000011f8 mov qword [var_48h], rsi ; argv\n| 0x000011fc lea rax, [str.Hello] ; 0x2004 ; \"Hello \"\n| 0x00001203 mov qword [var_30h], rax\n| 0x00001207 lea rax, [str.world] ; 0x200b ; \"world!\"\n| 0x0000120e mov qword [var_28h], rax\n| 0x00001212 mov rax, qword [var_30h]\n| 0x00001216 mov rdi, rax\n| 0x00001219 call sym.imp.strlen ; sym.imp.strlen ; size_t strlen(const char *s)\n| 0x0000121e mov qword [var_20h], rax\n| 0x00001222 mov rax, qword [var_28h]\n| 0x00001226 mov rdi, rax\n| 0x00001229 call sym.imp.strlen ; sym.imp.strlen ; size_t strlen(const char *s)\n| 0x0000122e mov qword [var_18h], rax\n| 0x00001232 mov rdx, qword [var_20h]\n| 0x00001236 mov rax, qword [var_18h]\n| 0x0000123a add rax, rdx\n| 0x0000123d add rax, 1\n| 0x00001241 mov rdi, rax\n| 0x00001244 call sym.imp.malloc ; sym.imp.malloc ; void *malloc(size_t size)\n| 0x00001249 mov qword [var_10h], rax\n| 0x0000124d cmp qword [var_10h], 0\n| ,=< 0x00001252 je 0x1292\n| | 0x00001254 mov rdx, qword [var_30h]\n| | 0x00001258 mov rax, qword [var_10h]\n| | 0x0000125c mov rsi, rdx\n| | 0x0000125f mov rdi, rax\n| | 0x00001262 call sym.imp.strcpy ; sym.imp.strcpy ; char *strcpy(char *dest, const char *src)\n| | 0x00001267 mov rdx, qword [var_28h]\n| | 0x0000126b mov rax, qword [var_10h]\n| | 0x0000126f mov rsi, rdx\n| | 0x00001272 mov rdi, rax\n| | 0x00001275 call sym.imp.strcat ; sym.imp.strcat ; char *strcat(char *s1, const char *s2)\n| | 0x0000127a mov rax, qword [var_10h]\n| | 0x0000127e mov rdi, rax\n| | 0x00001281 call sym.imp.puts ; sym.imp.puts ; int puts(const char *s)\n| | 0x00001286 mov rax, qword [var_10h]\n| | 0x0000128a mov rdi, rax\n| | 0x0000128d call sym.imp.free ; sym.imp.free ; void free(void *ptr)\n| `-> 0x00001292 mov eax, 0\n| 0x00001297 leave\n\\ 0x00001298 ret\n\n[0x000011e9]> aeim\n\n[0x000011e9]> aft\n\n[0x000011e9]> pdf\n ; DATA XREF from entry0 @ 0x1118\n ;-- rip:\n/ int main(int argc, char **argv, char **envp);\n| ; arg int argc @ rdi\n| ; arg char **argv @ rsi\n| ; var char **var_48h @ stack - 0x48\n| ; var int var_3ch @ stack - 0x3c\n| ; var const char *src @ stack - 0x30\n| ; var const char *s2 @ stack - 0x28\n| ; var size_t var_20h @ stack - 0x20\n| ; var size_t size @ stack - 0x18\n| ; var char *dest @ stack - 0x10\n| 0x000011e9 endbr64\n| 0x000011ed push rbp\n| 0x000011ee mov rbp, rsp\n| 0x000011f1 sub rsp, 0x40\n| 0x000011f5 mov dword [var_3ch], edi ; argc\n| 0x000011f8 mov qword [var_48h], rsi ; argv\n| 0x000011fc lea rax, [str.Hello] ; 0x2004 ; \"Hello \"\n| 0x00001203 mov qword [src], rax\n| 0x00001207 lea rax, [str.world] ; 0x200b ; \"world!\"\n| 0x0000120e mov qword [s2], rax\n| 0x00001212 mov rax, qword [src]\n| 0x00001216 mov rdi, rax ; const char *s\n| 0x00001219 call sym.imp.strlen ; sym.imp.strlen ; size_t strlen(const char *s)\n| 0x0000121e mov qword [var_20h], rax\n| 0x00001222 mov rax, qword [s2]\n| 0x00001226 mov rdi, rax ; const char *s\n| 0x00001229 call sym.imp.strlen ; sym.imp.strlen ; size_t strlen(const char *s)\n| 0x0000122e mov qword [size], rax\n| 0x00001232 mov rdx, qword [var_20h]\n| 0x00001236 mov rax, qword [size]\n| 0x0000123a add rax, rdx\n| 0x0000123d add rax, 1\n| 0x00001241 mov rdi, rax ; size_t size\n| 0x00001244 call sym.imp.malloc ; sym.imp.malloc ; void *malloc(size_t size)\n| 0x00001249 mov qword [dest], rax\n| 0x0000124d cmp qword [dest], 0\n| ,=< 0x00001252 je 0x1292\n| | 0x00001254 mov rdx, qword [src]\n| | 0x00001258 mov rax, qword [dest]\n| | 0x0000125c mov rsi, rdx ; const char *src\n| | 0x0000125f mov rdi, rax ; char *dest\n| | 0x00001262 call sym.imp.strcpy ; sym.imp.strcpy ; char *strcpy(char *dest, const char *src)\n| | 0x00001267 mov rdx, qword [s2]\n| | 0x0000126b mov rax, qword [dest]\n| | 0x0000126f mov rsi, rdx ; const char *s2\n| | 0x00001272 mov rdi, rax ; char *s1\n| | 0x00001275 call sym.imp.strcat ; sym.imp.strcat ; char *strcat(char *s1, const char *s2)\n| | 0x0000127a mov rax, qword [dest]\n| | 0x0000127e mov rdi, rax ; const char *s\n| | 0x00001281 call sym.imp.puts ; sym.imp.puts ; int puts(const char *s)\n| | 0x00001286 mov rax, qword [dest]\n| | 0x0000128a mov rdi, rax ; void *ptr\n| | 0x0000128d call sym.imp.free ; sym.imp.free ; void free(void *ptr)\n| `-> 0x00001292 mov eax, 0\n| 0x00001297 leave\n\\ 0x00001298 ret\n\n\nwin=spec\nspec.win.u32=unsigned int", "crumbs": [ "Analysis", - "47  Managing variables" + "48  Managing variables" ] }, { "objectID": "src/analysis/types.html", "href": "src/analysis/types.html", - "title": "48  Types", + "title": "49  Types", "section": "", - "text": "Rizin supports C-syntax data type definitions. Most of the related commands are located in t namespace:\n[0x00001100]> t?\nUsage: t[?] # Types, noreturn, signatures, C parser and more\n| t[j*l] [<type>] # List all types / Show type information\n| t- <type> # Remove the type\n| t-* # Remove all types\n| tc[dc] # List loaded types in C format\n| td <type> # Define type from C definition\n| te[jbcdf] # List loaded enums\n| tf[j-c?] # List loaded functions definitions\n| tn[j-?] # Manage noreturn function attributes and marks\n| to[es] # Open C header file and load types from it\n| tp[vx] # Print formatted type casted to the address\n| ts[jlcd] # List loaded structures\n| tt[jc] # List loaded typedefs\n| tu[jlcd] # List loaded unions\n| tx[fgl] # Type xrefs\nNote that the basic (atomic) types are not those from the C standard - not char, _Bool, or short. Because those types can be different from one platform to another, Rizin uses definite types like as int8_t or uint64_t and will convert int to int32_t or int64_t depending on the binary or debuggee platform/compiler.\nBasic types can be listed using the t command. For structured types, you can use ts, tu, or te for structs, unions, and enums, respectively:\n[0x000051c0]> t\nchar\nchar *\nint\nint16_t\nint32_t\nint64_t\nint8_t\nlong\nlong long\n...\n\n48.0.1 Loading types\nThere are three easy ways to define a new type: * Passing a string to the td command * Passing a file with the to <filename> command * Using your defined cfg.editor by calling the to - command\n[0x000051c0]> td \"struct foo {char* a; int b;}\"\n[0x000051c0]> cat ~/rizin-regressions/bins/headers/s3.h\nstruct S1 {\n int x[3];\n int y[4];\n int z;\n};\n[0x000051c0]> to ~/rizin-regressions/bins/headers/s3.h\n[0x000051c0]> ts\nfoo\nS1\nAlso, note there is a config option to specify include directories for types parsing\n[0x00000000]> el~dir.type\ndir.types: Default path to look for cparse type files\n[0x00000000]> e dir.types\n/usr/include\n\n\n48.0.2 Printing types\nNotice below we have used ts command, which basically converts the C type description into the sequence of pf commands. See more about print format.\nThe tp command uses the pf string to print all the members of type at the current offset/given address:\n[0x000051c0]> ts foo\npf zd a b\n[0x000051c0]> tp foo\n a : 0x000051c0 = 'hello'\n b : 0x000051cc = 10\n[0x000051c0]> tp foo 0x000053c0\n a : 0x000053c0 = 'world'\n b : 0x000053cc = 20\nAlso, you could fill your own data into the struct and print it using tpx command\n[0x000051c0]> tpx foo 4141414144141414141442001000000\n a : 0x000051c0 = AAAAD.....B\n b : 0x000051cc = 16\n\n\n48.0.3 Linking Types\nThe tp command only performs a temporary cast. We can use the avga command to define a global variable of a specified type, which is linked to an address.\n[0x000051c0]> avga struct_1 S1 @ 0x51cf\n[0x000051c0]> avg\nglobal struct S1 struct_1 @ 0x000051cf\nMoreover, the link will be shown in the disassembly output or visual mode:\n[0x000051c0 15% 300 /bin/ls]> pd $r @ entry0\n ;-- entry0:\n 0x000051c0 xor ebp, ebp\n 0x000051c2 mov r9, rdx\n 0x000051c5 pop rsi\n 0x000051c6 mov rdx, rsp\n 0x000051c9 and rsp, 0xfffffffffffffff0\n 0x000051cd push rax\n 0x000051ce push rsp\n(S1 struct_1)\n x : 0x000051cf = [ 2315619660, 1207959810, 34803085 ]\n y : 0x000051db = [ 2370306049, 4293315645, 3860201471, 4093649307 ]\n z : 0x000051eb = 4464399\n 0x000051f0 lea rdi, loc._edata ; 0x21f248\n 0x000051f7 push rbp\n 0x000051f8 lea rax, loc._edata ; 0x21f248\n 0x000051ff cmp rax, rdi\n 0x00005202 mov rbp, rsp\nOnce the struct is linked, Rizin tries to propagate structure offset in the function at the current offset, to run this analysis on the whole program or at any targeted functions after all structs are linked you have aat command:\n[0x00000000]> aat?\nUsage: aat [<func_name>] # Analyze all/given function to convert immediate to linked structure offsets\nNote sometimes the emulation may not be accurate, for example as below:\n|0x000006da push rbp\n|0x000006db mov rbp, rsp\n|0x000006de sub rsp, 0x10\n|0x000006e2 mov edi, 0x20 ; \"@\"\n|0x000006e7 call sym.imp.malloc ; void *malloc(size_t size)\n|0x000006ec mov qword [local_8h], rax\n|0x000006f0 mov rax, qword [local_8h]\n\nThe return value of malloc may differ between two emulations, so you have to set the hint for return value manually using ahr command, so run tl or aat command after setting up the return value hint.\n[0x000006da]> ahr?\nUsage: ahr <return> # Set function return value hint\n\n\n48.0.4 Structure Immediates\nThere is one more important aspect of using types in rizin - using aht you can change the immediate in the opcode to the structure offset. Let’s see a simple example of [R]SI-relative addressing\n[0x000052f0]> pd 1\n0x000052f0 mov rax, qword [rsi + 8] ; [0x8:8]=0\nHere 8 - is some offset in the memory, where rsi probably holds some structure pointer. Imagine that we have the following structures\n\n[0x000052f0]> td \"struct ms { char b[8]; int member1; int member2; };\"\n[0x000052f0]> td \"struct ms1 { uint64_t a; int member1; };\"\n[0x000052f0]> td \"struct ms2 { uint16_t a; int64_t b; int member1; };\"\nNow we need to set the proper structure member offset instead of 8 in this instruction. At first, we need to list available types matching this offset:\n[0x000052f0]> ahts 8\nms.member1\nms1.member1\nNote, that ms2 is not listed, because it has no members with offset 8. After listing available options we can link it to the chosen offset at the current address:\n[0x000052f0]> aht ms1.member1\n[0x000052f0]> pd 1\n0x000052f0 488b4608 mov rax, qword [rsi + ms1.member1] ; [0x8:8]=0\n\n\n48.0.5 Managing enums\n\nPrinting all fields in enum using te command\n\n[0x00000000]> td \"enum Foo {COW=1,BAR=2};\"\n[0x00000000]> te Foo\nCOW = 0x1\nBAR = 0x2\n\nFinding matching enum member for given bitfield and vice-versa\n\n[0x00000000]> te Foo 0x1\nCOW\n[0x00000000]> teb Foo COW\n0x1", + "text": "Rizin supports C-syntax data type definitions. Most of the related commands are located in t namespace:\n[0x00001100]> t?\nUsage: t[?] # Types, noreturn, signatures, C parser and more\n| t[j*l] [<type>] # List all types / Show type information\n| t- <type> # Remove the type\n| t-* # Remove all types\n| tc[dc] # List loaded types in C format\n| td <type> # Define type from C definition\n| te[jbcdf] # List loaded enums\n| tf[j-c?] # List loaded functions definitions\n| tn[j-?] # Manage noreturn function attributes and marks\n| to[es] # Open C header file and load types from it\n| tp[vx] # Print formatted type casted to the address\n| ts[jlcd] # List loaded structures\n| tt[jc] # List loaded typedefs\n| tu[jlcd] # List loaded unions\n| tx[fgl] # Type xrefs\nNote that the basic (atomic) types are not those from the C standard - not char, _Bool, or short. Because those types can be different from one platform to another, Rizin uses definite types like as int8_t or uint64_t and will convert int to int32_t or int64_t depending on the binary or debuggee platform/compiler.\nBasic types can be listed using the t command. For structured types, you can use ts, tu, or te for structs, unions, and enums, respectively:\n[0x000051c0]> t\nchar\nchar *\nint\nint16_t\nint32_t\nint64_t\nint8_t\nlong\nlong long\n...\n\n49.0.1 Loading types\nThere are three easy ways to define a new type: * Passing a string to the td command * Passing a file with the to <filename> command * Using your defined cfg.editor by calling the to - command\n[0x000051c0]> td \"struct foo {char* a; int b;}\"\n[0x000051c0]> cat ~/rizin-regressions/bins/headers/s3.h\nstruct S1 {\n int x[3];\n int y[4];\n int z;\n};\n[0x000051c0]> to ~/rizin-regressions/bins/headers/s3.h\n[0x000051c0]> ts\nfoo\nS1\nAlso, note there is a config option to specify include directories for types parsing\n[0x00000000]> el~dir.type\ndir.types: Default path to look for cparse type files\n[0x00000000]> e dir.types\n/usr/include\n\n\n49.0.2 Printing types\nNotice below we have used ts command, which basically converts the C type description into the sequence of pf commands. See more about print format.\nThe tp command uses the pf string to print all the members of type at the current offset/given address:\n[0x000051c0]> ts foo\npf zd a b\n[0x000051c0]> tp foo\n a : 0x000051c0 = 'hello'\n b : 0x000051cc = 10\n[0x000051c0]> tp foo 0x000053c0\n a : 0x000053c0 = 'world'\n b : 0x000053cc = 20\nAlso, you could fill your own data into the struct and print it using tpx command\n[0x000051c0]> tpx foo 4141414144141414141442001000000\n a : 0x000051c0 = AAAAD.....B\n b : 0x000051cc = 16\n\n\n49.0.3 Linking Types\nThe tp command only performs a temporary cast. We can use the avga command to define a global variable of a specified type, which is linked to an address.\n[0x000051c0]> avga struct_1 S1 @ 0x51cf\n[0x000051c0]> avg\nglobal struct S1 struct_1 @ 0x000051cf\nMoreover, the link will be shown in the disassembly output or visual mode:\n[0x000051c0 15% 300 /bin/ls]> pd $r @ entry0\n ;-- entry0:\n 0x000051c0 xor ebp, ebp\n 0x000051c2 mov r9, rdx\n 0x000051c5 pop rsi\n 0x000051c6 mov rdx, rsp\n 0x000051c9 and rsp, 0xfffffffffffffff0\n 0x000051cd push rax\n 0x000051ce push rsp\n(S1 struct_1)\n x : 0x000051cf = [ 2315619660, 1207959810, 34803085 ]\n y : 0x000051db = [ 2370306049, 4293315645, 3860201471, 4093649307 ]\n z : 0x000051eb = 4464399\n 0x000051f0 lea rdi, loc._edata ; 0x21f248\n 0x000051f7 push rbp\n 0x000051f8 lea rax, loc._edata ; 0x21f248\n 0x000051ff cmp rax, rdi\n 0x00005202 mov rbp, rsp\nOnce the struct is linked, Rizin tries to propagate structure offset in the function at the current offset, to run this analysis on the whole program or at any targeted functions after all structs are linked you have aat command:\n[0x00000000]> aat?\nUsage: aat [<func_name>] # Analyze all/given function to convert immediate to linked structure offsets\nNote sometimes the emulation may not be accurate, for example as below:\n|0x000006da push rbp\n|0x000006db mov rbp, rsp\n|0x000006de sub rsp, 0x10\n|0x000006e2 mov edi, 0x20 ; \"@\"\n|0x000006e7 call sym.imp.malloc ; void *malloc(size_t size)\n|0x000006ec mov qword [local_8h], rax\n|0x000006f0 mov rax, qword [local_8h]\n\nThe return value of malloc may differ between two emulations, so you have to set the hint for return value manually using ahr command, so run tl or aat command after setting up the return value hint.\n[0x000006da]> ahr?\nUsage: ahr <return> # Set function return value hint\n\n\n49.0.4 Structure Immediates\nThere is one more important aspect of using types in rizin - using aht you can change the immediate in the opcode to the structure offset. Let’s see a simple example of [R]SI-relative addressing\n[0x000052f0]> pd 1\n0x000052f0 mov rax, qword [rsi + 8] ; [0x8:8]=0\nHere 8 - is some offset in the memory, where rsi probably holds some structure pointer. Imagine that we have the following structures\n\n[0x000052f0]> td \"struct ms { char b[8]; int member1; int member2; };\"\n[0x000052f0]> td \"struct ms1 { uint64_t a; int member1; };\"\n[0x000052f0]> td \"struct ms2 { uint16_t a; int64_t b; int member1; };\"\nNow we need to set the proper structure member offset instead of 8 in this instruction. At first, we need to list available types matching this offset:\n[0x000052f0]> ahts 8\nms.member1\nms1.member1\nNote, that ms2 is not listed, because it has no members with offset 8. After listing available options we can link it to the chosen offset at the current address:\n[0x000052f0]> aht ms1.member1\n[0x000052f0]> pd 1\n0x000052f0 488b4608 mov rax, qword [rsi + ms1.member1] ; [0x8:8]=0\n\n\n49.0.5 Managing enums\n\nPrinting all fields in enum using te command\n\n[0x00000000]> td \"enum Foo {COW=1,BAR=2};\"\n[0x00000000]> te Foo\nCOW = 0x1\nBAR = 0x2\n\nFinding matching enum member for given bitfield and vice-versa\n\n[0x00000000]> te Foo 0x1\nCOW\n[0x00000000]> teb Foo COW\n0x1", "crumbs": [ "Analysis", - "48  Types" + "49  Types" ] }, { "objectID": "src/analysis/calling_conventions.html", "href": "src/analysis/calling_conventions.html", - "title": "49  Calling Conventions", + "title": "50  Calling Conventions", "section": "", "text": "Rizin uses calling conventions to help in identifying function formal arguments and return types. It is used also as a guide for basic function prototype and type propagation.\n[0x00000000]> afc?\nUsage: afc[lor] # Calling convention\n| afc [<convention>] # Set/Get calling convention for current function\n| afcl[j*kl] # List all available calling conventions\n| afco <db_path> # Open Calling Convention sdb profile from given path\n| afcr[j] # Show register usage for the current function\n[0x00000000]>\nTo list all available calling conventions for current architecture using afcl command\n[0x00000000]> afcl\namd64\namd64syscall\nms\nreg\nswift\nThe default calling convention for a particular architecture/binary is defined with analysis.cc for user-mode calls and analysis.syscc for syscalls.\nAll this information is loaded via sdb under /librz/analysis/d/cc-[arch]-[bits].sdb\ndefault.cc=amd64\n\nms=cc\ncc.ms.name=ms\ncc.ms.arg1=rcx\ncc.ms.arg2=rdx\ncc.ms.arg3=r8\ncc.ms.arg3=r9\ncc.ms.argn=stack\ncc.ms.ret=rax\ncc.x.argi=rax is used to set the ith argument of this calling convention to register name rax\ncc.x.argn=stack means that all the arguments (or the rest of them in case there was argi for any i as counting number) will be stored in the stack from left to right\ncc.x.argn=stack_rev same as cc.x.argn=stack except for it means argument are passed right to left", "crumbs": [ "Analysis", - "49  Calling Conventions" + "50  Calling Conventions" ] }, { "objectID": "src/analysis/vtables.html", "href": "src/analysis/vtables.html", - "title": "50  Virtual Tables", + "title": "51  Virtual Tables", "section": "", "text": "There is basic support of virtual tables parsing (RTTI and others). The most important thing before you start to perform such kind of analysis is to check if the analysis.cpp.abi option is set correctly and change it if needed.\nAll commands to work with virtual tables are located in the av namespace. Currently, the support is very basic, allowing you only to inspect parsed tables.\nUsage: av[j*gr?] # C++ vtables and RTTI\n| av[j*] # search for vtables in data sections and show results\n| avg[?] # Global variables\n| avr[j] # try to parse RTTI at vtable addr (see analysis.cpp.abi)\n| avra[j] # search for vtables and try to parse RTTI at each of them\n| avrr # recover class info from all findable RTTI (see ac)\n| avrD <classname> # demangle a class name from RTTI\nThe main commands here are av and avr. av lists all virtual tables found when Rizin opened the file. If you are not happy with the result you may want to try to parse a virtual table at a particular address with avr command. avra performs the search and parsing of all virtual tables in the binary, like Rizin does during the file opening.", "crumbs": [ "Analysis", - "50  Virtual Tables" + "51  Virtual Tables" ] }, { "objectID": "src/analysis/syscalls.html", "href": "src/analysis/syscalls.html", - "title": "51  Syscalls", + "title": "52  Syscalls", "section": "", "text": "Rizin allows manual search for assembly code looking like a syscall operation. For example on the ARM platform, usually, these are represented by the svc instruction, on the others, these can be different instructions, e.g. syscall on x86 PC.\n[0x0001ece0]> /ad/ svc\n...\n0x000187c2 # 2: svc 0x76\n0x000189ea # 2: svc 0xa9\n0x00018a0e # 2: svc 0x82\n...\nSyscalls detection is driven by asm.os, asm.bits, and asm.arch. Be sure to set those configuration options accordingly. You can use asl command to check if syscalls’ support is set up properly and as you expect. The command lists syscalls supported for your platform.\n[0x0001ece0]> asl\n...\nsd_softdevice_enable = 0x80.16\nsd_softdevice_disable = 0x80.17\nsd_softdevice_is_enabled = 0x80.18\n...\nIf you setup ESIL stack with aei or aeim, you can use /as command to search the addresses where particular syscalls were found and list them.\n[0x0001ece0]> aei\n[0x0001ece0]> /as\n0x000187c2 sd_ble_gap_disconnect\n0x000189ea sd_ble_gatts_sys_attr_set\n0x00018a0e sd_ble_gap_sec_info_reply\n...\nTo reduce searching time it is possible to restrict the searching range for only executable segments or sections with /as @e:search.in=io.maps.x\nUsing the ESIL emulation Rizin can print syscall arguments in the disassembly output. To enable the linear (but very rough) emulation use asm.emu configuration variable:\n[0x0001ece0]> e asm.emu=true\n[0x0001ece0]> s 0x000187c2\n[0x000187c2]> pdf~svc\n 0x000187c2 svc 0x76 ; 118 = sd_ble_gap_disconnect\n[0x000187c2]>\nIn case of executing aae (or aaaa which calls aae) command Rizin will push found syscalls to a special syscall. flagspace, which can be useful for automation purpose:\n[0x000187c2]> fs\n0 0 * imports\n1 0 * symbols\n2 1523 * functions\n3 420 * strings\n4 183 * syscalls\n[0x000187c2]> f~syscall\n...\n0x000187c2 1 syscall.sd_ble_gap_disconnect.0\n0x000189ea 1 syscall.sd_ble_gatts_sys_attr_set\n0x00018a0e 1 syscall.sd_ble_gap_sec_info_reply\n...\nIt also can be interactively navigated through within HUD mode (V_)\n0> syscall.sd_ble_gap_disconnect\n - 0x000187b2 syscall.sd_ble_gap_disconnect\n 0x000187c2 syscall.sd_ble_gap_disconnect.0\n 0x00018a16 syscall.sd_ble_gap_disconnect.1\n 0x00018b32 syscall.sd_ble_gap_disconnect.2\n 0x0002ac36 syscall.sd_ble_gap_disconnect.3\nWhen debugging in Rizin, you can use dcs to continue execution until the next syscall. You can also run dcs* to trace all syscalls.\n[0xf7fb9120]> dcs*\nRunning child until syscalls:-1 \nchild stopped with signal 133\n--> SN 0xf7fd3d5b syscall 45 brk (0xffffffda)\nchild stopped with signal 133\n--> SN 0xf7fd28f3 syscall 384 arch_prctl (0xffffffda 0x3001)\nchild stopped with signal 133\n--> SN 0xf7fc81b2 syscall 33 access (0xffffffda 0xf7fd8bf1)\nchild stopped with signal 133\nrizin also has a syscall name to syscall number utility. You can return the syscall name of a given syscall number or vice versa, without leaving the shell.\n[0x08048436]> asr 1\nexit\n[0x08048436]> asn write\n4\nSee as? for more information about the utility.", "crumbs": [ "Analysis", - "51  Syscalls" + "52  Syscalls" ] }, { "objectID": "src/analysis/emulation.html", "href": "src/analysis/emulation.html", - "title": "52  Emulation", + "title": "53  Emulation", "section": "", - "text": "52.1 Emulation in analysis loop\nOne of the most important things to remember in reverse engineering is the core difference between static analysis and dynamic analysis. As many already know, static analysis suffers from the path explosion problem, which is impossible to solve even in the most basic way without at least a partial emulation.\nThus, many professional reverse engineering tools use code emulation while performing an analysis of binary code, and Rizin is no different here.\nFor partial emulation (or imprecise full emulation) Rizin uses its own RzIL intermediate language, designed to replace current ESIL.\nRizin supports this kind of partial emulation for all platforms that implement ESIL uplifting (x86/x86_64, ARM, arm64, MIPS, PowerPC, SPARC, AVR, 8051, Game Boy, …).\nOne of the most common usages of such emulation is to calculate indirect jumps and conditional jumps.\nTo see the ESIL representation of the program one can use the ao command or enable the asm.esil configuration variable, to check if the program uplifted correctly, and to grasp how ESIL works:\nTo manually setup the ESIL imprecise emulation you need to run this command sequence:\nWhile performing emulation, please remember, that ESIL VM cannot emulate external calls or system calls, along with SIMD instructions. Thus, the most common scenario is to emulate only a small chunk of the code, like encryption/decryption, unpacking or calculating something.\nAfter we successfully set up the ESIL VM we can interact with it like with a usual debugging mode. The commands interface for ESIL VM is almost identical to the debugging one:\nIn visual mode, all the debugging hotkeys will work also in ESIL emulation mode.\nAlong with usual emulation, there is a possibility to record and replay mode:\nMore about this operation mode you can read in Reverse Debugging chapter.\nApart from the manual emulation mode, it can be used automatically in the analysis loop. For example, the aaaa command performs the ESIL emulation stage along with others. To disable or enable its usage you can use analysis.esil configuration variable. There is one more important option, though setting it might be quite dangerous, especially in the case of malware - emu.write which allows ESIL VM to modify memory. Sometimes it is required though, especially in the process of deobfuscating or unpacking code.\nTo show the process of emulation you can set asm.emu variable, which will show calculated register and memory values in disassembly comments:\nNote here likely comments, which indicates that ESIL emulation predicted for particular conditional jump to happen.\nApart from the basic ESIL VM setup, you can change the behavior with other options located in emu. and esil. configuration namespaces.\nFor manipulating ESIL working with memory and stack you can use the following options:", + "text": "53.1 Emulation in analysis loop\nOne of the most important things to remember in reverse engineering is the core difference between static analysis and dynamic analysis. As many already know, static analysis suffers from the path explosion problem, which is impossible to solve even in the most basic way without at least a partial emulation.\nThus, many professional reverse engineering tools use code emulation while performing an analysis of binary code, and Rizin is no different here.\nFor partial emulation (or imprecise full emulation) Rizin uses its own RzIL intermediate language, designed to replace current ESIL.\nRizin supports this kind of partial emulation for all platforms that implement ESIL uplifting (x86/x86_64, ARM, arm64, MIPS, PowerPC, SPARC, AVR, 8051, Game Boy, …).\nOne of the most common usages of such emulation is to calculate indirect jumps and conditional jumps.\nTo see the ESIL representation of the program one can use the ao command or enable the asm.esil configuration variable, to check if the program uplifted correctly, and to grasp how ESIL works:\nTo manually setup the ESIL imprecise emulation you need to run this command sequence:\nWhile performing emulation, please remember, that ESIL VM cannot emulate external calls or system calls, along with SIMD instructions. Thus, the most common scenario is to emulate only a small chunk of the code, like encryption/decryption, unpacking or calculating something.\nAfter we successfully set up the ESIL VM we can interact with it like with a usual debugging mode. The commands interface for ESIL VM is almost identical to the debugging one:\nIn visual mode, all the debugging hotkeys will work also in ESIL emulation mode.\nAlong with usual emulation, there is a possibility to record and replay mode:\nMore about this operation mode you can read in Reverse Debugging chapter.\nApart from the manual emulation mode, it can be used automatically in the analysis loop. For example, the aaaa command performs the ESIL emulation stage along with others. To disable or enable its usage you can use analysis.esil configuration variable. There is one more important option, though setting it might be quite dangerous, especially in the case of malware - emu.write which allows ESIL VM to modify memory. Sometimes it is required though, especially in the process of deobfuscating or unpacking code.\nTo show the process of emulation you can set asm.emu variable, which will show calculated register and memory values in disassembly comments:\nNote here likely comments, which indicates that ESIL emulation predicted for particular conditional jump to happen.\nApart from the basic ESIL VM setup, you can change the behavior with other options located in emu. and esil. configuration namespaces.\nFor manipulating ESIL working with memory and stack you can use the following options:", "crumbs": [ "Analysis", - "52  Emulation" + "53  Emulation" ] }, { "objectID": "src/analysis/emulation.html#emulation-in-analysis-loop", "href": "src/analysis/emulation.html#emulation-in-analysis-loop", - "title": "52  Emulation", + "title": "53  Emulation", "section": "", "text": "[0x00001660]> e asm.emu=true\n[0x00001660]> pdf\n. (fcn) fcn.00001660 40\n│ fcn.00001660 ();\n│ ; CALL XREF from 0x00001713 (entry2.fini)\n│ 0x00001660 lea rdi, obj.__progname ; 0x207220 ; rdi=0x207220 -> 0x464c457f\n│ 0x00001667 push rbp ; rsp=0xfffffffffffffff8\n│ 0x00001668 lea rax, obj.__progname ; 0x207220 ; rax=0x207220 -> 0x464c457f\n│ 0x0000166f cmp rax, rdi ; zf=0x1 -> 0x2464c45 ; cf=0x0 ; pf=0x1 -> 0x2464c45 ; sf=0x0 ; of=0x0\n│ 0x00001672 mov rbp, rsp ; rbp=0xfffffffffffffff8\n│ .─< 0x00001675 je 0x1690 ; rip=0x1690 -> 0x1f0fc35d ; likely\n│ │ 0x00001677 mov rax, qword [reloc._ITM_deregisterTMCloneTable] ; [0x206fd8:8]=0 ; rax=0x0\n│ │ 0x0000167e test rax, rax ; zf=0x1 -> 0x2464c45 ; pf=0x1 -> 0x2464c45 ; sf=0x0 ; cf=0x0 ; of=0x0\n│.──< 0x00001681 je 0x1690 ; rip=0x1690 -> 0x1f0fc35d ; likely\n│││ 0x00001683 pop rbp ; rbp=0xffffffffffffffff -> 0x4c457fff ; rsp=0x0\n│││ 0x00001684 jmp rax ; rip=0x0 ..\n│``─> 0x00001690 pop rbp ; rbp=0x10102464c457f ; rsp=0x8 -> 0x464c457f\n` 0x00001691 ret ; rip=0x0 ; rsp=0x10 -> 0x3e0003\n\n\n\n\nesil.stack to enable or disable temporary stack for asm.emu mode\nesil.stack.addr to set stack address in ESIL VM (like aeim command)\nesil.stack.size to set stack size in ESIL VM (like aeim command)\nesil.stack.depth limits the number of PUSH operations into the stack\nesil.romem specifies read-only access to the ESIL memory\nesil.fillstack and esil.stack.pattern allows you to use a various pattern for filling ESIL VM stack upon initialization\nesil.nonull when set stops ESIL execution upon NULL pointer read or write.", "crumbs": [ "Analysis", - "52  Emulation" + "53  Emulation" ] }, { "objectID": "src/analysis/symbols.html", "href": "src/analysis/symbols.html", - "title": "53  Symbols", + "title": "54  Symbols", "section": "", "text": "Rizin automatically parses available imports and exports sections in the binary, moreover, it can load additional debugging information if present. Two main formats are supported: DWARF and PDB (for Windows binaries). Note that, unlike many tools rizin doesn’t rely on Windows API to parse PDB files, thus they can be loaded on any other supported platform - e.g. Linux or OS X.\nDWARF debug info loads automatically by default because usually it’s stored right in the executable file. PDB is a bit of a different beast - it is always stored as a separate binary, thus the different logic of handling it.\nAt first, one of the common scenarios is to analyze the file from Windows distribution. In this case, all PDB files are available on the Microsoft server, which is by default is in options. See all pdb options in rizin:\n[0x00000000]> ell pdb\npdb.autoload = 0 ; Automatically load the required pdb files for loaded DLLs\npdb.extract = 1 ; Avoid extract of the pdb file, just download\npdb.server = https://msdl.microsoft.com/download/symbols ; Semi-colon separated list of base URLs for Microsoft symbol servers\npdb.symstore = /home/user/.local/share/rizin/pdb ; Path to downstream symbol store\nUsing the variable pdb.server you can change the address where Rizin will try to download the PDB file by the GUID stored in the executable header. You can make use of multiple symbol servers by separating each URL with a semicolon:\n[0x00000000]> e pdb.server=https://msdl.microsoft.com/download/symbols;https://symbols.mozilla.org/\nOn Windows, you can also use local network share paths (UNC paths) as symbol servers.\nBecause those PDB files are stored as “cab” archives on the server, pdb.extract=1 says to automatically extract them.\nNote that for the automatic downloading to work you need the “cabextract” tool, and wget/curl installed.\nSometimes you don’t need to do that from the Rizin itself, thus - two handy rz-bin options:\n -P Show debug/pdb information\n -PP Download pdb file for binary\nwhere -PP automatically downloads the pdb for the selected binary, using those pdb.* config options. -P will dump the contents of the PDB file, which is useful sometimes for a quick understanding of the symbols stored in it.\nApart from the basic scenario of just opening a file, PDB information can be additionally manipulated by the id commands:\n[0x000051c0]> id?\nUsage: id[jqp] # Debug commands\n| id[jq] # Show DWARF source lines information\n| idp[jidx] # PDB commands\nWhere idpi is basically the same as rz-bin -P. Note that idp can be also used not only in the static analysis mode but also in the debugging mode, even if connected via WinDbg.\nFor simplifying the loading PDBs, especially for the processes with many linked DLLs, Rizin can autoload all required PDBs automatically - you need just set the e pdb.autoload=true option. Then, if you load some file in debugging mode in Windows, using rizin -d file.exe or rizin -d 2345 (attach to pid 2345), all related PDB files will be loaded automatically.\nDWARF information loading, on the other hand, is completely automated. You don’t need to run any commands/change any options:\nrizin `which rz-bin`\n[0x00002437 8% 300 /usr/local/bin/rz-bin]> pd $r\n0x00002437 jne 0x2468 ;[1]\n0x00002439 cmp qword reloc.__cxa_finalize_224, 0\n0x00002441 push rbp\n0x00002442 mov rbp, rsp\n0x00002445 je 0x2453 ;[2]\n0x00002447 lea rdi, obj.__dso_handle ; 0x207c40 ; \"@| \"\n0x0000244e call 0x2360 ;[3]\n0x00002453 call sym.deregister_tm_clones ;[4]\n0x00002458 mov byte [obj.completed.6991], 1 ; obj.__TMC_END__ ; [0x2082f0:1]=0\n0x0000245f pop rbp\n0x00002460 ret\n0x00002461 nop dword [rax]\n0x00002468 ret\n0x0000246a nop word [rax + rax]\n;-- entry1.init:\n;-- frame_dummy:\n0x00002470 push rbp\n0x00002471 mov rbp, rsp\n0x00002474 pop rbp\n0x00002475 jmp sym.register_tm_clones ;[5]\n;-- blob_version:\n0x0000247a push rbp ; ../blob/version.c:18\n0x0000247b mov rbp, rsp\n0x0000247e sub rsp, 0x10\n0x00002482 mov qword [rbp - 8], rdi\n0x00002486 mov eax, 0x32 ; ../blob/version.c:24 ; '2'\n0x0000248b test al, al ; ../blob/version.c:19\n0x0000248d je 0x2498 ;[6]\n0x0000248f lea rax, str.2.0.1_182_gf1aa3aa4d ; 0x60b8 ; \"2.0.1-182-gf1aa3aa4d\"\n0x00002496 jmp 0x249f ;[7]\n0x00002498 lea rax, 0x000060cd\n0x0000249f mov rsi, qword [rbp - 8]\n0x000024a3 mov r8, rax\n0x000024a6 mov ecx, 0x40 ; section_end.ehdr\n0x000024ab mov edx, 0x40c0\n0x000024b0 lea rdi, str._s_2.1.0_git__d___linux_x86__d_git._s_n ; 0x60d0 ; \"%s 2.1.0-git %d @ linux-x86-%d git.%s\\n\"\n0x000024b7 mov eax, 0\n0x000024bc call 0x2350 ;[8]\n0x000024c1 mov eax, 0x66 ; ../blob/version.c:25 ; 'f'\n0x000024c6 test al, al\n0x000024c8 je 0x24d6 ;[9]\n0x000024ca lea rdi, str.commit:_f1aa3aa4d2599c1ad60e3ecbe5f4d8261b282385_build:_2017_11_06__12:18:39 ; ../blob/version.c:26 ; 0x60f8 ; \"commit: f1aa3aa4d2599c1ad60e3ecbe5f4d8261b282385 build: 2017-11-06__1\n0x000024d1 call sym.imp.puts ;[?]\n0x000024d6 mov eax, 0 ; ../blob/version.c:28\n0x000024db leave ; ../blob/version.c:29\n0x000024dc ret\n;-- rabin_show_help:\n0x000024dd push rbp ; .//rz-bin.c:27\nAs you can see, it loads function names and source line information.", "crumbs": [ "Analysis", - "53  Symbols" + "54  Symbols" ] }, { "objectID": "src/analysis/signatures.html", "href": "src/analysis/signatures.html", - "title": "54  Signatures", + "title": "55  Signatures", "section": "", - "text": "54.1 Signature matching\nRizin supports the HexRays FLIRT signature format, enabling users to effortlessly create, parse, or apply signatures on the go. Additionally, Rizin can automatically apply these signatures when the user defines the sigdb via the flirt.sigdb.path variable. All applied signatures are then stored within the flirt flag space.\nThe HexRays FLIRT format has two formats:\nSignature commands are available under the F command namespace:\nBefore applying a signature, you must first analyze the binary (see code analysis chapter).\nIn Rizin, there are two methods to apply signatures to a file: using sigdb or manually specifying the signature file.\nIf e flirt.sigdb.path is configured before executing the analysis (aaa command), then sigdb files are automatically applied to the binary. However, if a manual approach is preferred, it is possible to select the FLIRT signature file from sigdb using the Fa command. To list all available signature files in sigdb, use the Fl command.\nAn example of selecting sigdb signatures via Fa could be:\nTo manually apply a signature file, you need to use the Fs command.", + "text": "55.1 Signature matching\nRizin supports the HexRays FLIRT signature format, enabling users to effortlessly create, parse, or apply signatures on the go. Additionally, Rizin can automatically apply these signatures when the user defines the sigdb via the flirt.sigdb.path variable. All applied signatures are then stored within the flirt flag space.\nThe HexRays FLIRT format has two formats:\nSignature commands are available under the F command namespace:\nBefore applying a signature, you must first analyze the binary (see code analysis chapter).\nIn Rizin, there are two methods to apply signatures to a file: using sigdb or manually specifying the signature file.\nIf e flirt.sigdb.path is configured before executing the analysis (aaa command), then sigdb files are automatically applied to the binary. However, if a manual approach is preferred, it is possible to select the FLIRT signature file from sigdb using the Fa command. To list all available signature files in sigdb, use the Fl command.\nAn example of selecting sigdb signatures via Fa could be:\nTo manually apply a signature file, you need to use the Fs command.", "crumbs": [ "Analysis", - "54  Signatures" + "55  Signatures" ] }, { "objectID": "src/analysis/signatures.html#signature-matching", "href": "src/analysis/signatures.html#signature-matching", - "title": "54  Signatures", + "title": "55  Signatures", "section": "", "text": "[0x00409c70]> pdf\n ; CALL XREF from main @ 0x4017c1\n/ fcn.00409c70 (int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg5, int64_t arg6, int64_t arg7, int64_t arg8, int64_t arg9, int64_t arg10, int64_t arg11, int64_t arg_e0h);\n| ; var int64_t var_4h_2 @ rsp+0x4\n| ; var int64_t var_8h_2 @ rsp+0x8\n| ; var int64_t var_10h_2 @ rsp+0x10\n| ; var int64_t var_18h_2 @ rsp+0x18\n| ; var int64_t var_20h_2 @ rsp+0x20\n| ; var int64_t var_30h_2 @ rsp+0x30\n| ; var int64_t var_38h_2 @ rsp+0x38\n| ; var int64_t var_40h_2 @ rsp+0x40\n[0x00409c70]> e flirt.sigdb.path=/path/to/sigdb\n[0x00409c70]> Fa?\nUsage: Fa [<filter>] # Apply signatures from sigdb\n[0x00409c70]> Fl?\nUsage: Fl[t] # Lists all available signatures in sigdb (table mode)\n| Flt # Lists all available signatures in sigdb (table mode)\n[0x00409c70]> Flt:name/str/gcc\nbin arch bits name modules details \n--------------------------------------------------------------------------------------------\nelf x86 64 ubuntu-libgcc-10.sig 487 Ubuntu GCC support library Version 10 (rizin.re)\nelf x86 64 ubuntu-libgcc-11.sig 298 Ubuntu GCC support library Version 11 (rizin.re)\nelf x86 64 ubuntu-libgcc-12.sig 307 Ubuntu GCC support library Version 12 (rizin.re)\nelf x86 64 ubuntu-libgcc-7.sig 247 Ubuntu GCC support library Version 7 (rizin.re)\nelf x86 64 ubuntu-libgcc-8.sig 520 Ubuntu GCC support library Version 8 (rizin.re)\nelf x86 64 ubuntu-libgcc-9.sig 535 Ubuntu GCC support library Version 9 (rizin.re)\n[0x00409c70]> Fa gcc\nApplying elf/x86/64/ubuntu-libgcc-10.sig signature file\nApplying elf/x86/64/ubuntu-libgcc-11.sig signature file\nApplying elf/x86/64/ubuntu-libgcc-12.sig signature file\nApplying elf/x86/64/ubuntu-libgcc-7.sig signature file\nApplying elf/x86/64/ubuntu-libgcc-8.sig signature file\nApplying elf/x86/64/ubuntu-libgcc-9.sig signature file\n[0x00409c70]> pdf\n ; CALL XREF from main @ 0x4017c1\n ;-- fcn.00409c70:\n/ flirt.printf (int64_t arg1, int64_t arg2, int64_t arg3, int64_t arg4, int64_t arg5, int64_t arg6, int64_t arg7, int64_t arg8, int64_t arg9, int64_t arg10, int64_t arg11, int64_t arg_e0h);\n| ; var int64_t var_4h @ rsp+0xdc\n| ; var int64_t var_8h @ rsp+0xe0\n| ; var int64_t var_10h @ rsp+0xe8\n| ; var int64_t var_18h @ rsp+0xf0\n| \n\n$ rizin /path/to/binary/with/stripped.elf\n[0x00009690]> aaa\n[0x00009690]> Fs signature.sig # relative or absolutes paths are accepted\nFound 536 FLIRT signatures via signature.sig\n[0x00009690]>", "crumbs": [ "Analysis", - "54  Signatures" + "55  Signatures" ] }, { "objectID": "src/analysis/signatures.html#signature-creation", "href": "src/analysis/signatures.html#signature-creation", - "title": "54  Signatures", - "section": "54.2 Signature creation", - "text": "54.2 Signature creation\nBefore creating a signature, you must first analyze the binary (see code analysis chapter).\nYou can generate the signature by invoking the Fc <filename> command. You can customize the behavior of signature creation using the following options:\n\nSignature creation options:\n\nflirt.ignore.unknown: When enabled, during FLIRT creation, it will disregard any function starting with fcn., default: true.\nflirt.node.optimize: FLIRT optimization option when creating a signature file (none: 0, normal: 1, smallest: 2), default: 2.\n\n.sig (compressed format) specific options:\n\nflirt.sig.deflate: Enables or disables the FLIRT zlib compression when creating a signature file (available only for .sig files), default: true.\nflirt.sig.file: FLIRT file list (comma separated) for .sig format (msdos, win, os2, netware, unix, other, all, none), default: all.\nflirt.sig.library: FLIRT library name for .sig format, default: Built with rizin x.y.z.\nflirt.sig.os: FLIRT operating system list (comma separated) for .sig format (aixar, aout, ar, bin, coff, dos:com, dos:com:old, dos:exe, dos:exe:old, dosdrv, elf, intelhex, le, loader, lx, moshex, ne, nlm, omf, omflib, pe, pilot, srec, w32run, zip, all, none), default: all.\nflirt.sig.version: FLIRT version for .sig format default: 10.\n\nsigdb specific options:\n\nanalysis.apply.signature: Enables or disables the automatic application of signatures to the loaded binary, default: true.\nflirt.sigdb.load.extra: Load signatures from the extra path, default: true and its path can be found via rizin -H RZ_EXTRA_SIGDB.\nflirt.sigdb.load.home: Load signatures from the home path, default: true.\nflirt.sigdb.load.system: Load signatures from the system path, default: true and its path can be found via rizin -H RZ_SIGDB.\nflirt.sigdb.path: Additional user defined rizin sigdb location to load on the filesystem default: (empty).\n\n\nExample of signature creation in .sig (compressed) format:\n$ rizin /path/to/binary/with/symbols.elf\n[0x00009690]> aa\n[0x00009690]> # setting library name\n[0x00009690]> e flirt.sig.library=\"My Awesome Library Name\"\n[0x00009690]> # creating signature\n[0x00009690]> Fc signature.sig # relative or absolutes paths are accepted\n704 FLIRT signatures were written in 'signature.sig'\n[0x00009690]>\nExample of signature creation in .pat (human readable) format:\n$ rizin /path/to/binary/with/symbols.elf\n[0x00009690]> aa\n[0x00009690]> # disable internal node optimization\n[0x00009690]> e flirt.node.optimize=0\n[0x00009690]> # creating signature\n[0x00009690]> Fc signature.pat # relative or absolutes paths are accepted\n704 FLIRT signatures were written in 'signature.pat'\n[0x00009690]>\nYou can view the contents of a FLIRT signature file via Fd <filename>.\n[0x00009690]> Fd signature.sig\nSIG format\nSignature: Built with rizin x.y.z, 704 modules\nVersion: 10\nArchitecture: 0 (x86)\n09CA74..C30F1F00E9:\n 0. 00 0000 000D 0000:sock_state_cb\n0F:\n B6:\n 07:\n 3C..74..84C074..4C8D86FF000000EB..0F1F40003C..74..4939F074:\n 0. 00 0000 0103 0000:Curl_auth_digest_get_pair\n 84C0:\n 0F84........0FB60E84C90F84........4885D20F84........53:\n 0. 01 A5A9 0105 0000:Curl_strncasecompare\n 75..E9........0F1F400041......448D50E0448D429F4189C345:\n 0. 07 6545 009B 0000:Curl_strcasecompare\n 4F080FB7570883....66C1C20880....74..83....41B8010000006681..:\n 0. 00 0000 008A 0000:Curl_ipv6_scope.part.0\n 87910B00008B9748010000F7D0C0E80781..........0F9EC108C874..31:\n 0. 11 F2A8 00AF 0000:http_should_fail\n B707:\n 66C1C008C3:\n 0. 00 0000 0008 0000:Curl_read16_be\n C3:\n 0. 00 0000 0004 0000:Curl_read16_le\nYou can also utilize rz-sign to automatically create, convert, or dump FLIRT signatures:\n$ rz-sign -h\nUsage: rz-sign [options] [file]\n -h Show this help\n -a [-a] Add extra 'a' to analysis command (available only with -o option)\n -e [k=v] Set an evaluable config variable (available only with -o option)\n -c [output.pat] [input.sig] Parse a FLIRT signature and convert it to its other format\n -o [output.sig] [input.bin] Perform an analysis on the binary and generate the FLIRT signature\n -d [flirt.sig] Parse a FLIRT signature and dump its content\n -q Quiet mode\n -v Show version information\nExamples:\n rz-sign -d signature.sig\n rz-sign -c new_signature.pat old_signature.sig\n rz-sign -o libc.sig libc.so.6\n\n$ rz-sign -e \"flirt.sig.library=My Awesome Library Name\" -o signature.sig /path/to/binary/with/symbols.elf\nFor library files that use the .a or .la formats, it is highly recommended to unpack them using ar and utilize the .o files as sources for the signature files.", + "title": "55  Signatures", + "section": "55.2 Signature creation", + "text": "55.2 Signature creation\nBefore creating a signature, you must first analyze the binary (see code analysis chapter).\nYou can generate the signature by invoking the Fc <filename> command. You can customize the behavior of signature creation using the following options:\n\nSignature creation options:\n\nflirt.ignore.unknown: When enabled, during FLIRT creation, it will disregard any function starting with fcn., default: true.\nflirt.node.optimize: FLIRT optimization option when creating a signature file (none: 0, normal: 1, smallest: 2), default: 2.\n\n.sig (compressed format) specific options:\n\nflirt.sig.deflate: Enables or disables the FLIRT zlib compression when creating a signature file (available only for .sig files), default: true.\nflirt.sig.file: FLIRT file list (comma separated) for .sig format (msdos, win, os2, netware, unix, other, all, none), default: all.\nflirt.sig.library: FLIRT library name for .sig format, default: Built with rizin x.y.z.\nflirt.sig.os: FLIRT operating system list (comma separated) for .sig format (aixar, aout, ar, bin, coff, dos:com, dos:com:old, dos:exe, dos:exe:old, dosdrv, elf, intelhex, le, loader, lx, moshex, ne, nlm, omf, omflib, pe, pilot, srec, w32run, zip, all, none), default: all.\nflirt.sig.version: FLIRT version for .sig format default: 10.\n\nsigdb specific options:\n\nanalysis.apply.signature: Enables or disables the automatic application of signatures to the loaded binary, default: true.\nflirt.sigdb.load.extra: Load signatures from the extra path, default: true and its path can be found via rizin -H RZ_EXTRA_SIGDB.\nflirt.sigdb.load.home: Load signatures from the home path, default: true.\nflirt.sigdb.load.system: Load signatures from the system path, default: true and its path can be found via rizin -H RZ_SIGDB.\nflirt.sigdb.path: Additional user defined rizin sigdb location to load on the filesystem default: (empty).\n\n\nExample of signature creation in .sig (compressed) format:\n$ rizin /path/to/binary/with/symbols.elf\n[0x00009690]> aa\n[0x00009690]> # setting library name\n[0x00009690]> e flirt.sig.library=\"My Awesome Library Name\"\n[0x00009690]> # creating signature\n[0x00009690]> Fc signature.sig # relative or absolutes paths are accepted\n704 FLIRT signatures were written in 'signature.sig'\n[0x00009690]>\nExample of signature creation in .pat (human readable) format:\n$ rizin /path/to/binary/with/symbols.elf\n[0x00009690]> aa\n[0x00009690]> # disable internal node optimization\n[0x00009690]> e flirt.node.optimize=0\n[0x00009690]> # creating signature\n[0x00009690]> Fc signature.pat # relative or absolutes paths are accepted\n704 FLIRT signatures were written in 'signature.pat'\n[0x00009690]>\nYou can view the contents of a FLIRT signature file via Fd <filename>.\n[0x00009690]> Fd signature.sig\nSIG format\nSignature: Built with rizin x.y.z, 704 modules\nVersion: 10\nArchitecture: 0 (x86)\n09CA74..C30F1F00E9:\n 0. 00 0000 000D 0000:sock_state_cb\n0F:\n B6:\n 07:\n 3C..74..84C074..4C8D86FF000000EB..0F1F40003C..74..4939F074:\n 0. 00 0000 0103 0000:Curl_auth_digest_get_pair\n 84C0:\n 0F84........0FB60E84C90F84........4885D20F84........53:\n 0. 01 A5A9 0105 0000:Curl_strncasecompare\n 75..E9........0F1F400041......448D50E0448D429F4189C345:\n 0. 07 6545 009B 0000:Curl_strcasecompare\n 4F080FB7570883....66C1C20880....74..83....41B8010000006681..:\n 0. 00 0000 008A 0000:Curl_ipv6_scope.part.0\n 87910B00008B9748010000F7D0C0E80781..........0F9EC108C874..31:\n 0. 11 F2A8 00AF 0000:http_should_fail\n B707:\n 66C1C008C3:\n 0. 00 0000 0008 0000:Curl_read16_be\n C3:\n 0. 00 0000 0004 0000:Curl_read16_le\nYou can also utilize rz-sign to automatically create, convert, or dump FLIRT signatures:\n$ rz-sign -h\nUsage: rz-sign [options] [file]\n -h Show this help\n -a [-a] Add extra 'a' to analysis command (available only with -o option)\n -e [k=v] Set an evaluable config variable (available only with -o option)\n -c [output.pat] [input.sig] Parse a FLIRT signature and convert it to its other format\n -o [output.sig] [input.bin] Perform an analysis on the binary and generate the FLIRT signature\n -d [flirt.sig] Parse a FLIRT signature and dump its content\n -q Quiet mode\n -v Show version information\nExamples:\n rz-sign -d signature.sig\n rz-sign -c new_signature.pat old_signature.sig\n rz-sign -o libc.sig libc.so.6\n\n$ rz-sign -e \"flirt.sig.library=My Awesome Library Name\" -o signature.sig /path/to/binary/with/symbols.elf\nFor library files that use the .a or .la formats, it is highly recommended to unpack them using ar and utilize the .o files as sources for the signature files.", "crumbs": [ "Analysis", - "54  Signatures" + "55  Signatures" ] }, { "objectID": "src/analysis/signatures.html#signature-database-creation", "href": "src/analysis/signatures.html#signature-database-creation", - "title": "54  Signatures", - "section": "54.3 Signature database creation", - "text": "54.3 Signature database creation\nIt is possible to create personal sigdb using the sigdb tools and the scripts in sigdb source available in the RizinOrg repository.\n\nsigdb tools\n\ngenerate-pat-from-obj.py Generates unoptimized .pat signatures from .o, .lo, or .obj object files. The tool creates a new file with the same name as the original object file but with the extension .pat.\ngenerate-obj-from-lib.py Unpacks Windows .lib files into .o (object files). This tool accepts a folder containing all the .lib files to unpack as input and generates multiple directories (named after the respective libraries) along with their contents (beware that this tool requires linux utilities).\nlaunchpad-deb-scraper.py This script downloads deb packages from launchpad leveraging high-performance asynchronous i/o. It is possible to filter the deb packages by architecture.\n\nsigdb source\n\ngenerate-pat.py is a tool that generates a .pat file from one or multiple .pat files. It offers various options to automatically resolve conflicts. Additionally, it is possible to run it in test mode (also known as a dry run) to preview its actions without making any actual changes.\ngenerate-sig.py is a tool that is only used to generate .sig files for the release version of a signature database. this compress and automatically names the libraries following the sigdb source format.\n\n\nExample of sigdb generation using the tools mentioned above:\n# create output folders\n$ mkdir mysigdb mysigdb-extract mysigdb-source\n\n# check if there are lib files\n$ find libs/ -type f -name '*.lib'\nlibs/libcrypto.lib\nlibs/libssl.lib\n# unpack all lib files\n$ python ~/sigdb-tools/generate-obj-from-lib.py -v --input libs/\ninput dir: libs/\nfound 2 file to ingest\n\n[1|2] parsing libssl.lib\n[2|2] parsing libcrypto.lib\n\ndone.\n\n# create a sigdb source folder from the extracted files.\n$ python ~/sigdb-tools/generate-pat-from-obj.py -i libs/ --output mysigdb-extract\ninput dir: libs/\nfound 580 file to ingest\n\ndone.\n$ find mysigdb-extract/ -type f -name '*.pat' | head\nmysigdb-extract/coff/x86/64/libcrypto.lib.ext/bf_ofb64.c.obj.pat\nmysigdb-extract/coff/x86/64/libcrypto.lib.ext/aes_cfb.c.obj.pat\nmysigdb-extract/coff/x86/64/libcrypto.lib.ext/t_req.c.obj.pat\nmysigdb-extract/coff/x86/64/libcrypto.lib.ext/md5-mingw64-x86_64.S.obj.pat\nmysigdb-extract/coff/x86/64/libcrypto.lib.ext/tasn_utl.c.obj.pat\nmysigdb-extract/coff/x86/64/libcrypto.lib.ext/asn1_par.c.obj.pat\n...\n\n# create sigdb source folder structure.\n$ mkdir -p \"mysigdb-source/coff/x86/64/openssl_3_0_0\"\n\n# create sigdb library description files.\n# see https://github.com/rizinorg/sigdb-source/blob/main/README.md#mandatory-folder-structure\n$ echo \"OpenSSL 3.0.0 for Windows\" > \"mysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.description\"\n$ sha1sum openssl.3.0.0.zip > \"mysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.src.sha1\"\n\n# create sigdb source .pat from extracted files in mysigdb-extract\n$ python ~/sigdb-source/.scripts/generate-pat.py --auto --recursive -d \"mysigdb-extract/\" -o \"mysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.pat\"\noutput: mysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.pat\ninput: 577 pat files\nparsed a total of 6163 signatures and dropped 2082 (~34%) signatures. \nThere were 452 duplicates out of 4081 signatures (~11%).\nmysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.pat has been created\n\n# sigdb source directory is now complete.\n$ find mysigdb-source/ -type f\nmysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.description\nmysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.pat\nmysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.src.sha1\n\n# create release compressed files in mysigdb/ using mysigdb-source/.\n$ python generate-sig.py -s mysigdb-source/ -o mysigdb\nsource: mysigdb-source\noutput: mysigdb\nGenerating OpenSSL 3.0.0 for Windows signature (as openssl_3_0_0.sig) from openssl_3_0_0.pat\n\n# Use the generated sigdb with rizin.\n$ rizin -e \"flirt.sigdb.path=mysigdb/\" -qc 'Fl'\nbin arch bits name modules details \n------------------------------------------------------------------------------\ncoff x86 64 openssl_3_0_0.sig 3357 OpenSSL 3.0.0 for Windows (rizin.re)", + "title": "55  Signatures", + "section": "55.3 Signature database creation", + "text": "55.3 Signature database creation\nIt is possible to create personal sigdb using the sigdb tools and the scripts in sigdb source available in the RizinOrg repository.\n\nsigdb tools\n\ngenerate-pat-from-obj.py Generates unoptimized .pat signatures from .o, .lo, or .obj object files. The tool creates a new file with the same name as the original object file but with the extension .pat.\ngenerate-obj-from-lib.py Unpacks Windows .lib files into .o (object files). This tool accepts a folder containing all the .lib files to unpack as input and generates multiple directories (named after the respective libraries) along with their contents (beware that this tool requires linux utilities).\nlaunchpad-deb-scraper.py This script downloads deb packages from launchpad leveraging high-performance asynchronous i/o. It is possible to filter the deb packages by architecture.\n\nsigdb source\n\ngenerate-pat.py is a tool that generates a .pat file from one or multiple .pat files. It offers various options to automatically resolve conflicts. Additionally, it is possible to run it in test mode (also known as a dry run) to preview its actions without making any actual changes.\ngenerate-sig.py is a tool that is only used to generate .sig files for the release version of a signature database. this compress and automatically names the libraries following the sigdb source format.\n\n\nExample of sigdb generation using the tools mentioned above:\n# create output folders\n$ mkdir mysigdb mysigdb-extract mysigdb-source\n\n# check if there are lib files\n$ find libs/ -type f -name '*.lib'\nlibs/libcrypto.lib\nlibs/libssl.lib\n# unpack all lib files\n$ python ~/sigdb-tools/generate-obj-from-lib.py -v --input libs/\ninput dir: libs/\nfound 2 file to ingest\n\n[1|2] parsing libssl.lib\n[2|2] parsing libcrypto.lib\n\ndone.\n\n# create a sigdb source folder from the extracted files.\n$ python ~/sigdb-tools/generate-pat-from-obj.py -i libs/ --output mysigdb-extract\ninput dir: libs/\nfound 580 file to ingest\n\ndone.\n$ find mysigdb-extract/ -type f -name '*.pat' | head\nmysigdb-extract/coff/x86/64/libcrypto.lib.ext/bf_ofb64.c.obj.pat\nmysigdb-extract/coff/x86/64/libcrypto.lib.ext/aes_cfb.c.obj.pat\nmysigdb-extract/coff/x86/64/libcrypto.lib.ext/t_req.c.obj.pat\nmysigdb-extract/coff/x86/64/libcrypto.lib.ext/md5-mingw64-x86_64.S.obj.pat\nmysigdb-extract/coff/x86/64/libcrypto.lib.ext/tasn_utl.c.obj.pat\nmysigdb-extract/coff/x86/64/libcrypto.lib.ext/asn1_par.c.obj.pat\n...\n\n# create sigdb source folder structure.\n$ mkdir -p \"mysigdb-source/coff/x86/64/openssl_3_0_0\"\n\n# create sigdb library description files.\n# see https://github.com/rizinorg/sigdb-source/blob/main/README.md#mandatory-folder-structure\n$ echo \"OpenSSL 3.0.0 for Windows\" > \"mysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.description\"\n$ sha1sum openssl.3.0.0.zip > \"mysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.src.sha1\"\n\n# create sigdb source .pat from extracted files in mysigdb-extract\n$ python ~/sigdb-source/.scripts/generate-pat.py --auto --recursive -d \"mysigdb-extract/\" -o \"mysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.pat\"\noutput: mysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.pat\ninput: 577 pat files\nparsed a total of 6163 signatures and dropped 2082 (~34%) signatures. \nThere were 452 duplicates out of 4081 signatures (~11%).\nmysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.pat has been created\n\n# sigdb source directory is now complete.\n$ find mysigdb-source/ -type f\nmysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.description\nmysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.pat\nmysigdb-source/coff/x86/64/openssl_3_0_0/openssl_3_0_0.src.sha1\n\n# create release compressed files in mysigdb/ using mysigdb-source/.\n$ python generate-sig.py -s mysigdb-source/ -o mysigdb\nsource: mysigdb-source\noutput: mysigdb\nGenerating OpenSSL 3.0.0 for Windows signature (as openssl_3_0_0.sig) from openssl_3_0_0.pat\n\n# Use the generated sigdb with rizin.\n$ rizin -e \"flirt.sigdb.path=mysigdb/\" -qc 'Fl'\nbin arch bits name modules details \n------------------------------------------------------------------------------\ncoff x86 64 openssl_3_0_0.sig 3357 OpenSSL 3.0.0 for Windows (rizin.re)", "crumbs": [ "Analysis", - "54  Signatures" + "55  Signatures" ] }, { "objectID": "src/analysis/graphs.html", "href": "src/analysis/graphs.html", - "title": "55  Graph commands", + "title": "56  Graph commands", "section": "", - "text": "When analyzing data it is usually handy to have different ways to represent it in order to get new perspectives to allow the analyst to understand how different parts of the program interact.\nRepresenting basic block edges, function calls, string references as graphs show a very clear view of this information.\nRizin supports various types of graph available through commands starting with ag:\n[0x00005000]> ag?\nUsage: ag<?> # Analysis graph commands\n| aga <format>=ascii # Data reference graph\n| agA <format>=ascii # Global data references graph\n| agc <format>=ascii # Function callgraph\n| agC <format>=ascii # Global callgraph\n| agCi <format>=ascii # Inter-procedual control flow graph\n| agF <format>=ascii # Control flow graph (without calls)\n| agf <format>=ascii # Basic blocks function graph\n| agi <format>=ascii # Imports graph\n| agr <format>=ascii # References graph\n| agR <format>=ascii # Global references graph\n| ags <format>=ascii # Normal graph\n| agl <format>=ascii # Line graph\n| agx <format>=ascii # Cross-references graph\n| agI <format>=ascii # RzIL graph of the instruction at the current offset.\n| agg <format>=ascii # Custom graph\n| ag- # Clear the custom graph\n| agn[-] # Managing custom graph nodes\n| age[-] # Managing custom graph edges\n| agw <graphtype>=dataref <path> [-global] # Write to path or display graph image (see graph.gv.format)\n\nFormats:\n| ascii # Ascii art\n| cmd # rizin commands\n| dot # Graphviz dot\n| gml # Graph Modelling Language\n| json # json\n| json_disasm # json formatted disassembly\n| sdb # SDB key-value\n| interactive # Interactive ascii art\nThe structure of the commands is as follows: ag <graph type> <output format>.\nFor example, agi dot displays the imports graph in dot format, while agg json outputs the custom graph in JSON format.\nHere’s a short description for every output format available:\n\n55.0.1 Ascii Art (e.g. agf)\nDisplays the graph directly to stdout using ASCII art to represent blocks and edges.\nWarning: displaying large graphs directly to stdout might prove to be computationally expensive and will make Rizin not responsive for some time. In case of doubt, prefer using the interactive view (explained below).\n\n\n55.0.2 Interactive Ascii Art (e.g. agf interactive)\nDisplays the ASCII graph in an interactive view similar to VV which allows to move the screen, zoom in / zoom out, …\n\n\n55.0.3 Graphviz dot (e.g. agf dot)\nPrints the dot source code representing the graph, which can be interpreted by programs such as graphviz or online viewers like webgraphviz.\n\n\n55.0.4 JSON (e.g. agf json)\nPrints a JSON string representing the graph.\n\nIn the case of the f format (basic blocks of function), it will have detailed information about the function and will also contain the disassembly of the function (use J format for the formatted disassembly).\nIn all other cases, it will only have basic information about the nodes of the graph (id, title, body, and edges).\n\n\n\n55.0.5 Graph Modelling Language (e.g. agf gml)\nPrints the GML source code representing the graph, which can be interpreted by programs such as yEd\n\n\n55.0.6 SDB key-value (e.g. agf sdb)\nPrints key-value strings representing the graph that was stored by sdb (Rizin’s string database).\n\n\n55.0.7 Rizin custom graph commands (e.g. agg)\nPrints rizin commands that would recreate the desired graph. The commands to construct the graph are agn [title] [body] to add a node and age [title1] [title2] to add an edge. The [body] field can be expressed in base64 to include special formatting (such as newlines).\nTo easily execute the printed commands, it is possible to prepend a dot to the command (.agg).\n\n\n55.0.8 Web / image (e.g. agw)\nRizin will convert the graph to dot format, use the dot program to convert it to a .gif image and then try to find an already installed viewer on your system (xdg-open, open, …) and display the graph there.\nThe extension of the output image can be set with the graph.gv.format config variable. Available extensions are png, jpg, pdf, ps, svg, json.\nNote: for particularly large graphs, the most recommended extension is svg as it will produce images of much smaller size", + "text": "When analyzing data it is usually handy to have different ways to represent it in order to get new perspectives to allow the analyst to understand how different parts of the program interact.\nRepresenting basic block edges, function calls, string references as graphs show a very clear view of this information.\nRizin supports various types of graph available through commands starting with ag:\n[0x00005000]> ag?\nUsage: ag<?> # Analysis graph commands\n| aga <format>=ascii # Data reference graph\n| agA <format>=ascii # Global data references graph\n| agc <format>=ascii # Function callgraph\n| agC <format>=ascii # Global callgraph\n| agCi <format>=ascii # Inter-procedual control flow graph\n| agF <format>=ascii # Control flow graph (without calls)\n| agf <format>=ascii # Basic blocks function graph\n| agi <format>=ascii # Imports graph\n| agr <format>=ascii # References graph\n| agR <format>=ascii # Global references graph\n| ags <format>=ascii # Normal graph\n| agl <format>=ascii # Line graph\n| agx <format>=ascii # Cross-references graph\n| agI <format>=ascii # RzIL graph of the instruction at the current offset.\n| agg <format>=ascii # Custom graph\n| ag- # Clear the custom graph\n| agn[-] # Managing custom graph nodes\n| age[-] # Managing custom graph edges\n| agw <graphtype>=dataref <path> [-global] # Write to path or display graph image (see graph.gv.format)\n\nFormats:\n| ascii # Ascii art\n| cmd # rizin commands\n| dot # Graphviz dot\n| gml # Graph Modelling Language\n| json # json\n| json_disasm # json formatted disassembly\n| sdb # SDB key-value\n| interactive # Interactive ascii art\nThe structure of the commands is as follows: ag <graph type> <output format>.\nFor example, agi dot displays the imports graph in dot format, while agg json outputs the custom graph in JSON format.\nHere’s a short description for every output format available:\n\n56.0.1 Ascii Art (e.g. agf)\nDisplays the graph directly to stdout using ASCII art to represent blocks and edges.\nWarning: displaying large graphs directly to stdout might prove to be computationally expensive and will make Rizin not responsive for some time. In case of doubt, prefer using the interactive view (explained below).\n\n\n56.0.2 Interactive Ascii Art (e.g. agf interactive)\nDisplays the ASCII graph in an interactive view similar to VV which allows to move the screen, zoom in / zoom out, …\n\n\n56.0.3 Graphviz dot (e.g. agf dot)\nPrints the dot source code representing the graph, which can be interpreted by programs such as graphviz or online viewers like webgraphviz.\n\n\n56.0.4 JSON (e.g. agf json)\nPrints a JSON string representing the graph.\n\nIn the case of the f format (basic blocks of function), it will have detailed information about the function and will also contain the disassembly of the function (use J format for the formatted disassembly).\nIn all other cases, it will only have basic information about the nodes of the graph (id, title, body, and edges).\n\n\n\n56.0.5 Graph Modelling Language (e.g. agf gml)\nPrints the GML source code representing the graph, which can be interpreted by programs such as yEd\n\n\n56.0.6 SDB key-value (e.g. agf sdb)\nPrints key-value strings representing the graph that was stored by sdb (Rizin’s string database).\n\n\n56.0.7 Rizin custom graph commands (e.g. agg)\nPrints rizin commands that would recreate the desired graph. The commands to construct the graph are agn [title] [body] to add a node and age [title1] [title2] to add an edge. The [body] field can be expressed in base64 to include special formatting (such as newlines).\nTo easily execute the printed commands, it is possible to prepend a dot to the command (.agg).\n\n\n56.0.8 Web / image (e.g. agw)\nRizin will convert the graph to dot format, use the dot program to convert it to a .gif image and then try to find an already installed viewer on your system (xdg-open, open, …) and display the graph there.\nThe extension of the output image can be set with the graph.gv.format config variable. Available extensions are png, jpg, pdf, ps, svg, json.\nNote: for particularly large graphs, the most recommended extension is svg as it will produce images of much smaller size", "crumbs": [ "Analysis", - "55  Graph commands" + "56  Graph commands" ] }, { "objectID": "src/analysis/cpu_platform_profiles.html", "href": "src/analysis/cpu_platform_profiles.html", - "title": "56  CPU and platform profiles", + "title": "57  CPU and platform profiles", "section": "", - "text": "56.1 The motivation\nThe computer ecosystem, especially in embedded systems is vast and growing and is thus diverse and is full of trivial differences. CPUs and development boards differ by minor and sometimes large differences in their design, ports, MMIO registers and other peripherals. Rizin handles these differences by storing the data regarding each CPUs and platforms in SDB files in a standard format, instead of hardcoding them with each of the disassembler plugins. This information will be parsed and added as flags and comments during the analysis loop and will show up in the disassembly and other places, making reverse engineering on those particular chips ets is much easier. This also helps in easy addition of a new port, in maintenance and in user-friendliness.", + "text": "57.1 The motivation\nThe computer ecosystem, especially in embedded systems is vast and growing and is thus diverse and is full of trivial differences. CPUs and development boards differ by minor and sometimes large differences in their design, ports, MMIO registers and other peripherals. Rizin handles these differences by storing the data regarding each CPUs and platforms in SDB files in a standard format, instead of hardcoding them with each of the disassembler plugins. This information will be parsed and added as flags and comments during the analysis loop and will show up in the disassembly and other places, making reverse engineering on those particular chips ets is much easier. This also helps in easy addition of a new port, in maintenance and in user-friendliness.", "crumbs": [ "Analysis", - "56  CPU and platform profiles" + "57  CPU and platform profiles" ] }, { "objectID": "src/analysis/cpu_platform_profiles.html#how-it-works", "href": "src/analysis/cpu_platform_profiles.html#how-it-works", - "title": "56  CPU and platform profiles", - "section": "56.2 How it works", - "text": "56.2 How it works\n\n56.2.1 CPU profiles\nAll the specifics pertaining to a CPU is written down in a CPU profile. It is designed in a way that allows you to enter CPU specific values like: size of the RAM (RAM_SIZE), size of the ROM (ROM_SIZE) and many more. CPU profiles can be selected using the configuration variable asm.cpu. Firstly, Rizin checks whether the CPU profile exists for the selected CPU and architecture. If it exists, Rizin generates the filepath of the profile and gets to a stage where it’s ready to be loaded up. During analysis (aa), it’s loaded up and the values are parsed and handled. CPU profiles also allow you to add information regarding the IO and extended IO registers of a CPU. The information pertaining to the IO and extended IO registers are added as flags at their corresponding offsets.\nThe CPU profile of AVR’s ATTiny88 CPU looks like this:\nRAM_SIZE=512\nROM_SIZE=8192\nINTERRUPT_VECTOR_SIZE=2\n\nPINB=io\nPINB.address=0x03\nDDRB=io\nDDRB.address=0x04\nPORTB=io\nHere, PINB is the name and io is the type of the port and this will be added as a flag at the offset 0x03. The type can be ext_io if it’s an extended IO register, as well. Both will be added as flags and the only difference between them is that they will be added in different flagspaces.\nCPU profiles also support mapping the ROM. According to the ROM_ADDRESS and ROM_SIZE, a section named .rom will be added during analysis.\n\n56.2.1.1 Adding CPU profiles\nCPU profiles are stored in SDB files under the directory lirbz/asm/cpus and that’s where you will have to put your new profile. The files follow a naming convention like arch-cpu. You can see the complete list of things that are parsed at librz/analysis/arch_profile.c and if necessary, a new key can be easily added.\nTo add a new CPU profile, firstly make sure that you have the name of the CPU defined in the list of CPUs defined by the variable cpus in the corresponding architecture’s disassembler plugin (RzAsmPlugin). Then, simply add the SDB file in the directory, add the entry in the meson.build of the same directory and build again. Choose the right CPU and architecture and analyze again (aa) to load up the CPU profile.\nFor reference, you can see the previously added CPU profile of ATmega16 here: librz/asm/cpus/avr-ATmega16.sdb.txt.\n\n\n\n56.2.2 Platform profiles\nPlatform profiles are designed with an idea to support adding information that is pertaining to a specific board or a microcontroller. For example, most of the Raspberry Pi-s use a specific Broadcom chip and its peripherals like registers and interrupts will be the same for all Raspberry Pi-s. These profiles can be selected using the configuration variable asm.platforms and is loaded during analysis (aa). If you run e asm.platform=?, you can see the supported platforms by the selected architecture and CPU.\nLet’s have a look at Broadcom 2835’s platform profile:\nAUX_IRQ=name\nAUX_IRQ.address=0x7e215000\nAUX_IRQ.comment=Auxiliary Interrupt status\n\nAUX_MU_IO_REG=name\nAUX_MU_IO_REG.address=0x7e215040\nAUX_MU_IO_REG.comment=Mini UART I/O Data\nJust like in CPU profiles, the name will be added as a flag and the comment as a comment (CCu).\n\n56.2.2.1 Adding platform profiles\nPlatform profiles are stored in librz/asm/platforms/ and that’s where you will have to put your profile. They follow a naming convention like arch-cpu-platform.\nTo add a new platform profile, we will have to define the name of the platform in the variable platforms in the RzAsmPlugin definition corresponding architecture’s disassembler plugin. You will also need to add the CPU is it’s not already added. Then, add the entry in the meson.build of the same directory and build again. Choose the right CPU, architecture and platform and analyze again (aa).\nYou can also check out the platform profiles that were previously added at librz/asm/platforms/arm-arm1176-bcm2835.sdb.txt.", + "title": "57  CPU and platform profiles", + "section": "57.2 How it works", + "text": "57.2 How it works\n\n57.2.1 CPU profiles\nAll the specifics pertaining to a CPU is written down in a CPU profile. It is designed in a way that allows you to enter CPU specific values like: size of the RAM (RAM_SIZE), size of the ROM (ROM_SIZE) and many more. CPU profiles can be selected using the configuration variable asm.cpu. Firstly, Rizin checks whether the CPU profile exists for the selected CPU and architecture. If it exists, Rizin generates the filepath of the profile and gets to a stage where it’s ready to be loaded up. During analysis (aa), it’s loaded up and the values are parsed and handled. CPU profiles also allow you to add information regarding the IO and extended IO registers of a CPU. The information pertaining to the IO and extended IO registers are added as flags at their corresponding offsets.\nThe CPU profile of AVR’s ATTiny88 CPU looks like this:\nRAM_SIZE=512\nROM_SIZE=8192\nINTERRUPT_VECTOR_SIZE=2\n\nPINB=io\nPINB.address=0x03\nDDRB=io\nDDRB.address=0x04\nPORTB=io\nHere, PINB is the name and io is the type of the port and this will be added as a flag at the offset 0x03. The type can be ext_io if it’s an extended IO register, as well. Both will be added as flags and the only difference between them is that they will be added in different flagspaces.\nCPU profiles also support mapping the ROM. According to the ROM_ADDRESS and ROM_SIZE, a section named .rom will be added during analysis.\n\n57.2.1.1 Adding CPU profiles\nCPU profiles are stored in SDB files under the directory lirbz/asm/cpus and that’s where you will have to put your new profile. The files follow a naming convention like arch-cpu. You can see the complete list of things that are parsed at librz/analysis/arch_profile.c and if necessary, a new key can be easily added.\nTo add a new CPU profile, firstly make sure that you have the name of the CPU defined in the list of CPUs defined by the variable cpus in the corresponding architecture’s disassembler plugin (RzAsmPlugin). Then, simply add the SDB file in the directory, add the entry in the meson.build of the same directory and build again. Choose the right CPU and architecture and analyze again (aa) to load up the CPU profile.\nFor reference, you can see the previously added CPU profile of ATmega16 here: librz/asm/cpus/avr-ATmega16.sdb.txt.\n\n\n\n57.2.2 Platform profiles\nPlatform profiles are designed with an idea to support adding information that is pertaining to a specific board or a microcontroller. For example, most of the Raspberry Pi-s use a specific Broadcom chip and its peripherals like registers and interrupts will be the same for all Raspberry Pi-s. These profiles can be selected using the configuration variable asm.platforms and is loaded during analysis (aa). If you run e asm.platform=?, you can see the supported platforms by the selected architecture and CPU.\nLet’s have a look at Broadcom 2835’s platform profile:\nAUX_IRQ=name\nAUX_IRQ.address=0x7e215000\nAUX_IRQ.comment=Auxiliary Interrupt status\n\nAUX_MU_IO_REG=name\nAUX_MU_IO_REG.address=0x7e215040\nAUX_MU_IO_REG.comment=Mini UART I/O Data\nJust like in CPU profiles, the name will be added as a flag and the comment as a comment (CCu).\n\n57.2.2.1 Adding platform profiles\nPlatform profiles are stored in librz/asm/platforms/ and that’s where you will have to put your profile. They follow a naming convention like arch-cpu-platform.\nTo add a new platform profile, we will have to define the name of the platform in the variable platforms in the RzAsmPlugin definition corresponding architecture’s disassembler plugin. You will also need to add the CPU is it’s not already added. Then, add the entry in the meson.build of the same directory and build again. Choose the right CPU, architecture and platform and analyze again (aa).\nYou can also check out the platform profiles that were previously added at librz/asm/platforms/arm-arm1176-bcm2835.sdb.txt.", "crumbs": [ "Analysis", - "56  CPU and platform profiles" + "57  CPU and platform profiles" ] }, { "objectID": "src/scripting/intro.html", "href": "src/scripting/intro.html", - "title": "57  Scripting", + "title": "58  Scripting", "section": "", "text": "Rizin provides a wide set of a features to automate boring work. It ranges from the simple sequencing of the commands to the calling scripts/another programs via IPC (Inter-Process Communication), called rz-pipe.\nAs mentioned a few times before there is an ability to sequence commands using ; semicolon operator.\n[0x00404800]> pd 1 ; ao 1\n 0x00404800 b827e66100 mov eax, 0x61e627 ; \"tab\"\naddress: 0x404800\nopcode: mov eax, 0x61e627\nprefix: 0\nbytes: b827e66100\nptr: 0x0061e627\nrefptr: 0\nsize: 5\ntype: mov\nesil: 6415911,rax,=\nstack: null\nfamily: cpu\n[0x00404800]>\nIt simply runs the second command after finishing the first one, like in a shell.\nThe second important way to sequence the commands is with a simple pipe |\nao|grep address\nNote, the | pipe only can pipe output of rizin commands to external (shell) commands, like system programs or builtin shell commands.\nThere is a similar way to sequence rizin commands, using the backtick operator `command`. The quoted part will undergo command substitution and the output will be used as an argument of the command line.\nFor example, we want to see a few bytes of the memory at the address referred to by the ‘mov eax, addr’ instruction. We can do that without jumping to it, using a sequence of commands:\n[0x00404800]> pd 1\n 0x00404800 b827e66100 mov eax, 0x61e627 ; \"tab\"\n[0x00404800]> ao\naddress: 0x404800\nopcode: mov eax, 0x61e627\nprefix: 0\nbytes: b827e66100\nptr: 0x0061e627\nrefptr: 0\nsize: 5\ntype: mov\nesil: 6415911,rax,=\nstack: null\nfamily: cpu\n\n[0x00404800]> ao~ptr[1]\n0x0061e627\n0\n\n[0x00404800]> px 10 @ `ao~ptr[1]`\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\n0x0061e627 7461 6200 2e69 6e74 6572 tab..inter\nAnd of course it’s possible to redirect the output of a rizin command into a file, using the > and >> commands\n[0x00404800]> px 10 @ `ao~ptr[1]` > example.txt\n[0x00404800]> px 10 @ `ao~ptr[1]` >> example.txt\nThe %$? command describes several helpful variables you can use to do similar actions even more easily, like the $v “immediate value” variable, or the $m opcode memory reference variable.", "crumbs": [ "Scripting", - "57  Scripting" + "58  Scripting" ] }, { "objectID": "src/scripting/loops.html", "href": "src/scripting/loops.html", - "title": "58  Loops", + "title": "59  Loops", "section": "", "text": "One of the most common task in automation is looping through something, there are multiple ways to do this in rizin. You can find all these loops under @@?.\nWe can loop over flags:\n@@f:flagname-regex\nFor example, we want to see function information with afi command:\n[0x004047d6]> afi\n#\noffset: 0x004047d0\nname: entry0\nsize: 42\nrealsz: 42\nstackframe: 0\ncall-convention: amd64\ncyclomatic-complexity: 1\nbits: 64\ntype: fcn [NEW]\nnum-bbs: 1\nedges: 0\nend-bbs: 1\ncall-refs: 0x00402450 C\ndata-refs: 0x004136c0 0x00413660 0x004027e0\ncode-xrefs:\ndata-xrefs:\nlocals:0\nargs: 0\ndiff: type: new\n[0x004047d6]>\nNow let’s say, for example, that we’d like see a particular field from this output for all functions found by analysis. We can do that with a loop over all function flags (whose names begin with fcn.):\n[0x004047d6]> fs functions\n[0x004047d6]> afi @@f:fcn.* ~name\nThis command will extract the name field from the afi output of every flag with a name matching the regexp fcn.*.\nThere are other loops, for example one called @@F runs your command on every function found by rizin:\n[0x004047d6]> afi @@F ~name\nWe can also loop over a list of offsets, using the following syntax:\n@@=1 2 3 ... N\nFor example, say we want to see the opcode information for 2 offsets: the current one, and at current + 2:\n[0x004047d6]> ao @@=$$ $$+2\naddress: 0x4047d6\nopcode: mov rdx, rsp\nprefix: 0\nbytes: 4889e2\nrefptr: 0\nsize: 3\ntype: mov\nesil: rsp,rdx,=\nstack: null\nfamily: cpu\naddress: 0x4047d8\nopcode: loop 0x404822\nprefix: 0\nbytes: e248\nrefptr: 0\nsize: 2\ntype: cjmp\nesil: 1,rcx,-=,rcx,?{,4212770,rip,=,}\njump: 0x00404822\nfail: 0x004047da\nstack: null\ncond: al\nfamily: cpu\nNote we’re using the $$ variable which evaluates to the current offset. Also note that $$+2 is evaluated before looping, so we can use the simple arithmetic expressions.\nA third way to loop is by having the offsets be loaded from a file. This file should contain one offset per line.\n[0x004047d0]> ?v $$ > offsets.txt\n[0x004047d0]> ?v $$+2 >> offsets.txt\n[0x004047d0]> !cat offsets.txt\n4047d0\n4047d2\n[0x004047d0]> pi 1 @@.offsets.txt\nxor ebp, ebp\nmov r9, rdx\nIf you want to iterate over all instructions of a basic block, you can do:\n[0x004047d0]> pi 1 @@i\nendbr64\npush rbx\ntest rdi, rdi\nje 0x14635\nIn this example the command pi 1 runs over all the instructions in the current basic block.\nIf you want to iterate over all instructions of all basic blocks of the current function, you can do:\n[0x004047d0]> pi 1 @@i @@b\nendbr64 \npush rbx \ntest rdi, rdi\nje 0x14635\nmov esi, 0x2f \nmov rbx, rdi\n[... cut for example ...]\nmov rbx, r8 \njmp 0x1461a \nmov rax, qword [reloc.stderr]\nmov edx, 0x37 \nmov esi, 1 \nlea rdi, str.A_NULL_argv_0__was_passed_through_an_exec_system_call. \nmov rcx, qword [rax]\ncall sym.imp.fwrite\ncall sym.imp.abort\nOr if you want to make the split between basic blocks clearer:\n[0x004047d0]> (_;pi 1 @@i; ?e)() @@b\nendbr64 \npush rbx \ntest rdi, rdi\nje 0x14635\n\nmov esi, 0x2f \nmov rbx, rdi\n[... cut for example ...]\nmov rbx, r8 \njmp 0x1461a \n\nmov rax, qword [reloc.stderr]\nmov edx, 0x37 \nmov esi, 1 \nlea rdi, str.A_NULL_argv_0__was_passed_through_an_exec_system_call. \nmov rcx, qword [rax]\ncall sym.imp.fwrite\ncall sym.imp.abort", "crumbs": [ "Scripting", - "58  Loops" + "59  Loops" ] }, { "objectID": "src/scripting/macros.html", "href": "src/scripting/macros.html", - "title": "59  Macros", + "title": "60  Macros", "section": "", - "text": "Apart from simple sequencing and looping, Rizin allows to write simple macros, using this construction:\n[0x00404800]> (qwe; pd 4; ao)\nThis will define a macro called ‘qwe’ which runs sequentially first ‘pd 4’ then ‘ao’. Calling the macro using syntax .(macro) is simple:\n[0x00404800]> (qwe; pd 4; ao)\n[0x00404800]> .(qwe)\n0x00404800 mov eax, 0x61e627 ; \"tab\"\n0x00404805 push rbp\n0x00404806 sub rax, section_end.LOAD1\n0x0040480c mov rbp, rsp\n\naddress: 0x404800\nopcode: mov eax, 0x61e627\nprefix: 0\nbytes: b827e66100\nptr: 0x0061e627\nrefptr: 0\nsize: 5\ntype: mov\nesil: 6415911,rax,=\nstack: null\nfamily: cpu\n[0x00404800]>\nTo list available macros simply call (*:\n[0x00404800]> (*\n(qwe ; pd 4; ao)\nAnd if you want to remove some macro, just add ‘-’ before the name:\n[0x00404800]> (-qwe)\nMacro 'qwe' removed.\n[0x00404800]>\nMoreover, it’s possible to create a macro that takes arguments, which comes in handy in some simple scripting situations. To create a macro that takes arguments you simply add them to macro definition.\n[0x00404800]> s entry0\n[0x004047d0]> (foo x y; pd $0; sd +$1)\n[0x004047d0]> .(foo 5 6)\n;-- entry0:\n0x004047d0 xor ebp, ebp\n0x004047d2 mov r9, rdx\n0x004047d5 pop rsi\n0x004047d6 mov rdx, rsp\n0x004047d9 and rsp, 0xfffffffffffffff0\n[0x004047d6]>\nAs you can see, the arguments are named by index, starting from 0: $0, $1, …\nTo run a macro multiple times with different arguments, a convenient way is to use ..(:\n[0x004047d6]> s entry0\n[0x004047d0]> ..(foo 3 5 2 4)\n;-- entry0:\n0x004047d0 xor ebp, ebp\n0x004047d2 mov r9, rdx\n0x004047d5 pop rsi\n0x004047d5 pop rsi\n0x004047d6 mov rdx, rsp\n[0x004047d9]>\n\n60 Aliases\nRizin also offers aliases which might help you save time by quickly executing your most used commands. They are under $?.\nThe general usage of the feature is: $alias=cmd\n[0x00404800]> $disas=pdf\nThe above command will create an alias disas for pdf. The following command prints the disassembly of the main function.\n[0x00404800]> $disas @ main\nApart from commands, you can also alias a text to be printed, when called.\n[0x00404800]> $my_alias=$test input\n[0x00404800]> $my_alias\ntest input\nTo undefine alias, use $alias=:\n[0x00404800]> $pmore='b 300;px'\n[0x00404800]> $\n$pmore\n[0x00404800]> $pmore=\n[0x00404800]> $\n\nA single $ in the above will list all defined aliases. It’s also possible check the aliased command of an alias:\n[0x00404800]> $pmore?\nb 200; px\nCan we create an alias contains alias? The answer is yes:\n[0x00404800]> $pStart='s 0x0;$pmore'\n[0x00404800]> $pStart\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\n0x00000000 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............\n0x00000010 0300 3e00 0100 0000 1014 0000 0000 0000 ..>.............\n0x00000020 4000 0000 0000 0000 5031 0000 0000 0000 @.......P1......\n0x00000030 0000 0000 4000 3800 0d00 4000 1e00 1d00 ....@.8...@.....\n0x00000040 0600 0000 0400 0000 4000 0000 0000 0000 ........@.......\n0x00000050 4000 0000 0000 0000 4000 0000 0000 0000 @.......@.......\n0x00000060 d802 0000 0000 0000 d802 0000 0000 0000 ................\n0x00000070 0800 0000 0000 0000 0300 0000 0400 0000 ................\n0x00000080 1803 0000 0000 0000 1803 0000 0000 0000 ................\n0x00000090 1803 0000 0000 0000 1c00 0000 0000 0000 ................\n0x000000a0 1c00 0000 0000 0000 0100 0000 0000 0000 ................\n0x000000b0 0100 0000 0400 0000 0000 0000 0000 0000 ................\n0x000000c0 0000 0000 0000 0000 ........\n[0x00000000]>", + "text": "Apart from simple sequencing and looping, Rizin allows to write simple macros, using this construction:\n[0x00404800]> (qwe; pd 4; ao)\nThis will define a macro called ‘qwe’ which runs sequentially first ‘pd 4’ then ‘ao’. Calling the macro using syntax .(macro) is simple:\n[0x00404800]> (qwe; pd 4; ao)\n[0x00404800]> .(qwe)\n0x00404800 mov eax, 0x61e627 ; \"tab\"\n0x00404805 push rbp\n0x00404806 sub rax, section_end.LOAD1\n0x0040480c mov rbp, rsp\n\naddress: 0x404800\nopcode: mov eax, 0x61e627\nprefix: 0\nbytes: b827e66100\nptr: 0x0061e627\nrefptr: 0\nsize: 5\ntype: mov\nesil: 6415911,rax,=\nstack: null\nfamily: cpu\n[0x00404800]>\nTo list available macros simply call (*:\n[0x00404800]> (*\n(qwe ; pd 4; ao)\nAnd if you want to remove some macro, just add ‘-’ before the name:\n[0x00404800]> (-qwe)\nMacro 'qwe' removed.\n[0x00404800]>\nMoreover, it’s possible to create a macro that takes arguments, which comes in handy in some simple scripting situations. To create a macro that takes arguments you simply add them to macro definition.\n[0x00404800]> s entry0\n[0x004047d0]> (foo x y; pd $0; sd +$1)\n[0x004047d0]> .(foo 5 6)\n;-- entry0:\n0x004047d0 xor ebp, ebp\n0x004047d2 mov r9, rdx\n0x004047d5 pop rsi\n0x004047d6 mov rdx, rsp\n0x004047d9 and rsp, 0xfffffffffffffff0\n[0x004047d6]>\nAs you can see, the arguments are named by index, starting from 0: $0, $1, …\nTo run a macro multiple times with different arguments, a convenient way is to use ..(:\n[0x004047d6]> s entry0\n[0x004047d0]> ..(foo 3 5 2 4)\n;-- entry0:\n0x004047d0 xor ebp, ebp\n0x004047d2 mov r9, rdx\n0x004047d5 pop rsi\n0x004047d5 pop rsi\n0x004047d6 mov rdx, rsp\n[0x004047d9]>\n\n61 Aliases\nRizin also offers aliases which might help you save time by quickly executing your most used commands. They are under $?.\nThe general usage of the feature is: $alias=cmd\n[0x00404800]> $disas=pdf\nThe above command will create an alias disas for pdf. The following command prints the disassembly of the main function.\n[0x00404800]> $disas @ main\nApart from commands, you can also alias a text to be printed, when called.\n[0x00404800]> $my_alias=$test input\n[0x00404800]> $my_alias\ntest input\nTo undefine alias, use $alias=:\n[0x00404800]> $pmore='b 300;px'\n[0x00404800]> $\n$pmore\n[0x00404800]> $pmore=\n[0x00404800]> $\n\nA single $ in the above will list all defined aliases. It’s also possible check the aliased command of an alias:\n[0x00404800]> $pmore?\nb 200; px\nCan we create an alias contains alias? The answer is yes:\n[0x00404800]> $pStart='s 0x0;$pmore'\n[0x00404800]> $pStart\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\n0x00000000 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............\n0x00000010 0300 3e00 0100 0000 1014 0000 0000 0000 ..>.............\n0x00000020 4000 0000 0000 0000 5031 0000 0000 0000 @.......P1......\n0x00000030 0000 0000 4000 3800 0d00 4000 1e00 1d00 ....@.8...@.....\n0x00000040 0600 0000 0400 0000 4000 0000 0000 0000 ........@.......\n0x00000050 4000 0000 0000 0000 4000 0000 0000 0000 @.......@.......\n0x00000060 d802 0000 0000 0000 d802 0000 0000 0000 ................\n0x00000070 0800 0000 0000 0000 0300 0000 0400 0000 ................\n0x00000080 1803 0000 0000 0000 1803 0000 0000 0000 ................\n0x00000090 1803 0000 0000 0000 1c00 0000 0000 0000 ................\n0x000000a0 1c00 0000 0000 0000 0100 0000 0000 0000 ................\n0x000000b0 0100 0000 0400 0000 0000 0000 0000 0000 ................\n0x000000c0 0000 0000 0000 0000 ........\n[0x00000000]>", "crumbs": [ "Scripting", - "59  Macros" + "60  Macros" ] }, { "objectID": "src/scripting/rz-pipe.html", "href": "src/scripting/rz-pipe.html", - "title": "60  Rz-pipe", + "title": "61  Rz-pipe", "section": "", - "text": "60.1 Examples\nThe rz-pipe module permits interacting with Rizin instances in different methods:", + "text": "61.1 Examples\nThe rz-pipe module permits interacting with Rizin instances in different methods:", "crumbs": [ "Scripting", - "60  Rz-pipe" + "61  Rz-pipe" ] }, { "objectID": "src/scripting/rz-pipe.html#examples", "href": "src/scripting/rz-pipe.html#examples", - "title": "60  Rz-pipe", + "title": "61  Rz-pipe", "section": "", - "text": "60.1.1 Python\n$ pip install rzpipe\nimport rzpipe\n\nrz = rzpipe.open(\"/bin/ls\")\nrz.cmd('aa')\nprint(rz.cmd(\"afl\"))\nprint(rz.cmdj(\"aflj\")) # evaluates JSONs and returns an object\n\n\n60.1.2 Haskell\nimport RzPipe\nimport qualified Data.ByteString.Lazy as L\n\nshowMainFunction ctx = do\n cmd ctx \"s main\"\n L.putStr =<< cmd ctx \"pD `fl $$`\"\n\nmain = do\n -- Run rizin locally\n open \"/bin/ls\" >>= showMainFunction\n -- Connect to rizin via HTTP (e.g. if \"rizin -qc=h /bin/ls\" is running)\n open \"http://127.0.0.1:9090\" >>= showMainFunction\n\n\n60.1.3 OCaml\nlet result = Rz.with_command ~cmd:\"/j chown\" \"/bin/ls\"\nPrintf.printf \"Rizin output is: %s\" result\n\n\n60.1.4 Rust\n#[macro_use]\nextern crate rzpipe;\nextern crate serde_json;\nuse rzpipe::RzPipe;\nfn main() {\n let path = Some(\"/bin/ls\".to_owned());\n let mut rzp = open_pipe!(path).unwrap();\n println!(\"{}\", rzp.cmd(\"?e Hello World\").unwrap());\n if let Ok(json) = rzp.cmdj(\"ij\") {\n println!(\"{}\", serde_json::to_string_pretty(&json).unwrap());\n println!(\"ARCH {}\", json[\"bin\"][\"arch\"]);\n }\n rzp.close();\n}\n\n\n60.1.5 Ruby\nrequire './rzpipe'\n\nbegin\n rzp = RzPipe.new\nrescue Exception => e\n rzp = RzPipe.new '/bin/ls'\nend\n puts rzp.cmd 'a'\n puts rzp.cmd 'pd 10 main'\n rzp.quit", + "text": "61.1.1 Python\n$ pip install rzpipe\nimport rzpipe\n\nrz = rzpipe.open(\"/bin/ls\")\nrz.cmd('aa')\nprint(rz.cmd(\"afl\"))\nprint(rz.cmdj(\"aflj\")) # evaluates JSONs and returns an object\n\n\n61.1.2 Haskell\nimport RzPipe\nimport qualified Data.ByteString.Lazy as L\n\nshowMainFunction ctx = do\n cmd ctx \"s main\"\n L.putStr =<< cmd ctx \"pD `fl $$`\"\n\nmain = do\n -- Run rizin locally\n open \"/bin/ls\" >>= showMainFunction\n -- Connect to rizin via HTTP (e.g. if \"rizin -qc=h /bin/ls\" is running)\n open \"http://127.0.0.1:9090\" >>= showMainFunction\n\n\n61.1.3 OCaml\nlet result = Rz.with_command ~cmd:\"/j chown\" \"/bin/ls\"\nPrintf.printf \"Rizin output is: %s\" result\n\n\n61.1.4 Rust\n#[macro_use]\nextern crate rzpipe;\nextern crate serde_json;\nuse rzpipe::RzPipe;\nfn main() {\n let path = Some(\"/bin/ls\".to_owned());\n let mut rzp = open_pipe!(path).unwrap();\n println!(\"{}\", rzp.cmd(\"?e Hello World\").unwrap());\n if let Ok(json) = rzp.cmdj(\"ij\") {\n println!(\"{}\", serde_json::to_string_pretty(&json).unwrap());\n println!(\"ARCH {}\", json[\"bin\"][\"arch\"]);\n }\n rzp.close();\n}\n\n\n61.1.5 Ruby\nrequire './rzpipe'\n\nbegin\n rzp = RzPipe.new\nrescue Exception => e\n rzp = RzPipe.new '/bin/ls'\nend\n puts rzp.cmd 'a'\n puts rzp.cmd 'pd 10 main'\n rzp.quit", "crumbs": [ "Scripting", - "60  Rz-pipe" + "61  Rz-pipe" ] }, { "objectID": "src/debugger/intro.html", "href": "src/debugger/intro.html", - "title": "61  Debugger", + "title": "62  Debugger", "section": "", "text": "Debuggers are implemented as IO plugins. Therefore, rizin can handle different URI types for spawning, attaching and controlling processes. The complete list of IO plugins can be viewed with rizin -L. Those that have “d” in the first column (“rwd”) support debugging. For example:\nr_d debug Debug a program or pid. dbg:///bin/ls, dbg://1388 (LGPL3)\nrwd gdb Attach to gdbserver, 'qemu -s', gdb://localhost:1234 (LGPL3)\nThere are different backends for many target architectures and operating systems, e.g., GNU/Linux, Windows, macOS, Net/Free/OpenBSD and Solaris.\nProcess memory is treated as a plain file. All mapped memory pages of a debugged program and its libraries can be read and interpreted as code or data structures.\nCommunication between Rizin and the debugger IO layer is wrapped into system() calls, which accept a string as an argument, and executes it as a command. An answer is then buffered in the output console, its contents can be additionally processed by a script. Access to the IO system is achieved with R!. Most IO plugins provide help with R!? or R!help. For example:\n$ rizin -d /bin/ls\n...\n[0x7fc15afa3cc0]> R!help\nUsage: R!cmd args\n R!ptrace - use ptrace io\n R!mem - use /proc/pid/mem io if possible\n R!pid - show targeted pid\n R!pid <#> - select new pid\nIn general, debugger commands are portable between architectures and operating systems. Still, as Rizin tries to support the same functionality for all target architectures and operating systems, certain things have to be handled separately. They include injecting shellcodes and handling exceptions. For example, in MIPS targets there is no hardware-supported single-stepping feature. In this case, Rizin provides its own implementation for single-step by using a mix of code analysis and software breakpoints.\nTo get basic help for the debugger, type d?:\n[0x000000000000]> d?\nUsage: d<?> # Debugger commands\n| db[?] # Breakpoints commands\n| dc[?] # Continue execution\n| dd[-lsdrw] # Debug file descriptors commands\n| de[lcs?] # Manage ESIL watchpoints\n| dg [<filename>] # Generate core dump file\n| do<rec> # Debug (re)open commands\n| ds[?] # Debug step commands\n| dt[?] # Trace commands\n| di[j*q] # Debug information\n| dk[lnNo] # Debug signals management\n| dl[l] # Debug handler\n| dm[?] # Memory map commands\n| dp[?] # List or attach to process or thread\n| dr[?] # CPU Registers\n| dw [<pid>] # Block prompt until <pid> dies\n| dW[i] # Windows process commands\n| dx[aers] # Code injection commands\nTo restart your debugging session, you can use one of oo commands, depending on desired behavior:\n[0x00000000]> oo?\nUsage: oo[+bcdmn?] # Reopen current file\n| oo [<fd>] # Reopen current file or file <fd>\n| oo+ [<fd>] # Reopen current file or file <fd> in write mode\n| oob [<baddr>] # Reopen current file and reload binary information\n| ooc # Reopen current file as if restarting rizin\n| ood[fr] # Reopen current file in debug mode\n| oom # Reopen curent file in malloc://\n| oon # Reopen curent file without loading binary information\n| oon+ # Reopen curent file in write-mode without loading binary information\n| oonn # Reopen curent file without loading binary information but with header flags\n| oonn+ # Reopen curent file in write-mode without loading binary information but with header flags", "crumbs": [ "Debugger", - "61  Debugger" + "62  Debugger" ] }, { "objectID": "src/debugger/getting_started.html", "href": "src/debugger/getting_started.html", - "title": "62  Getting Started", + "title": "63  Getting Started", "section": "", - "text": "62.1 Small session in Rizin debugger", + "text": "63.1 Small session in Rizin debugger", "crumbs": [ "Debugger", - "62  Getting Started" + "63  Getting Started" ] }, { "objectID": "src/debugger/getting_started.html#small-session-in-rizin-debugger", "href": "src/debugger/getting_started.html#small-session-in-rizin-debugger", - "title": "62  Getting Started", + "title": "63  Getting Started", "section": "", "text": "rizin -d /bin/ls: Opens rizin with file /bin/ls in debugger mode using the rizin native debugger, but does not run the program. You’ll see a prompt (rizin) - all examples are from this prompt.\ndb @ flag: place a breakpoint at flag, where flag can be either an address or a function name\ndb- @ flag: remove the breakpoint at flag, where flag can be either an address or a function name\ndbl: show list of breakpoint\ndc: run the program\ndr: Show registers state\ndrr: Show registers references (telescoping) (like peda)\nds: Step into instruction\ndso: Step over instruction\ndbt: Display backtrace\ndm: Show memory maps\ndk <signal>: Send KILL signal to child\nood: reopen in debug mode\nood arg1 arg2: reopen in debug mode with arg1 and arg2", "crumbs": [ "Debugger", - "62  Getting Started" + "63  Getting Started" ] }, { "objectID": "src/debugger/migration.html", "href": "src/debugger/migration.html", - "title": "63  Migration from IDA, GDB or WinDBG", + "title": "64  Migration from IDA, GDB or WinDBG", "section": "", - "text": "63.1 How to run the program using the debugger\nrizin -d /bin/ls - start in debugger mode => [video]", + "text": "64.1 How to run the program using the debugger\nrizin -d /bin/ls - start in debugger mode => [video]", "crumbs": [ "Debugger", - "63  Migration from IDA, GDB or WinDBG" + "64  Migration from IDA, GDB or WinDBG" ] }, { "objectID": "src/debugger/migration.html#how-do-i-attachdetach-to-running-process-gdb--p", "href": "src/debugger/migration.html#how-do-i-attachdetach-to-running-process-gdb--p", - "title": "63  Migration from IDA, GDB or WinDBG", - "section": "63.2 How do I attach/detach to running process (gdb -p)?", - "text": "63.2 How do I attach/detach to running process (gdb -p)?\nrizin -d <pid> - attach to process\nrizin ptrace://pid - same as above, but only for io (not debugger backend hooked)\n[0x7fff6ad90028]> o-225 - close fd=225 (listed in o~[1]:0)\nrizin -D gdb gdb://localhost:1234 - attach to gdbserver", + "title": "64  Migration from IDA, GDB or WinDBG", + "section": "64.2 How do I attach/detach to running process (gdb -p)?", + "text": "64.2 How do I attach/detach to running process (gdb -p)?\nrizin -d <pid> - attach to process\nrizin ptrace://pid - same as above, but only for io (not debugger backend hooked)\n[0x7fff6ad90028]> o-225 - close fd=225 (listed in o~[1]:0)\nrizin -D gdb gdb://localhost:1234 - attach to gdbserver", "crumbs": [ "Debugger", - "63  Migration from IDA, GDB or WinDBG" + "64  Migration from IDA, GDB or WinDBG" ] }, { "objectID": "src/debugger/migration.html#how-to-set-argsenvironment-variableload-a-specific-libraries-for-the-debugging-session-of-rizin", "href": "src/debugger/migration.html#how-to-set-argsenvironment-variableload-a-specific-libraries-for-the-debugging-session-of-rizin", - "title": "63  Migration from IDA, GDB or WinDBG", - "section": "63.3 How to set args/environment variable/load a specific libraries for the debugging session of rizin?", - "text": "63.3 How to set args/environment variable/load a specific libraries for the debugging session of rizin?\nUse rz-run (libpath=$PWD:/tmp/lib, arg2=hello, setenv=FOO=BAR …) see rz-run -h / man rz-run", + "title": "64  Migration from IDA, GDB or WinDBG", + "section": "64.3 How to set args/environment variable/load a specific libraries for the debugging session of rizin?", + "text": "64.3 How to set args/environment variable/load a specific libraries for the debugging session of rizin?\nUse rz-run (libpath=$PWD:/tmp/lib, arg2=hello, setenv=FOO=BAR …) see rz-run -h / man rz-run", "crumbs": [ "Debugger", - "63  Migration from IDA, GDB or WinDBG" + "64  Migration from IDA, GDB or WinDBG" ] }, { "objectID": "src/debugger/migration.html#how-to-script-rizin", "href": "src/debugger/migration.html#how-to-script-rizin", - "title": "63  Migration from IDA, GDB or WinDBG", - "section": "63.4 How to script rizin?", - "text": "63.4 How to script rizin?\nrizin -i <scriptfile> ... - run a script after loading the file => [video]\nrizin -I <scriptfile> ... - run a script before loading the file\nrizin -c $@ | awk $@ - run through awk to get asm from function => [link]\n[0x80480423]> . scriptfile - interpret this file => [video]\n[0x80480423]> #!c - enter C repl (see #! to list all available RLang plugins) => [video], everything have to be done in an oneliner or a .c file must be passed as an argument.\nTo get #!python and much more, just build rizin-bindings", + "title": "64  Migration from IDA, GDB or WinDBG", + "section": "64.4 How to script rizin?", + "text": "64.4 How to script rizin?\nrizin -i <scriptfile> ... - run a script after loading the file => [video]\nrizin -I <scriptfile> ... - run a script before loading the file\nrizin -c $@ | awk $@ - run through awk to get asm from function => [link]\n[0x80480423]> . scriptfile - interpret this file => [video]\n[0x80480423]> #!c - enter C repl (see #! to list all available RLang plugins) => [video], everything have to be done in an oneliner or a .c file must be passed as an argument.\nTo get #!python and much more, just build rizin-bindings", "crumbs": [ "Debugger", - "63  Migration from IDA, GDB or WinDBG" + "64  Migration from IDA, GDB or WinDBG" ] }, { "objectID": "src/debugger/migration.html#how-to-list-source-code-as-in-gdb-list", "href": "src/debugger/migration.html#how-to-list-source-code-as-in-gdb-list", - "title": "63  Migration from IDA, GDB or WinDBG", - "section": "63.5 How to list Source code as in gdb list?", - "text": "63.5 How to list Source code as in gdb list?\nCL @ sym.main - though the feature is highly experimental", + "title": "64  Migration from IDA, GDB or WinDBG", + "section": "64.5 How to list Source code as in gdb list?", + "text": "64.5 How to list Source code as in gdb list?\nCL @ sym.main - though the feature is highly experimental", "crumbs": [ "Debugger", - "63  Migration from IDA, GDB or WinDBG" + "64  Migration from IDA, GDB or WinDBG" ] }, { "objectID": "src/debugger/migration.html#equivalent-of-set-follow-fork-mode-gdb-command", "href": "src/debugger/migration.html#equivalent-of-set-follow-fork-mode-gdb-command", - "title": "63  Migration from IDA, GDB or WinDBG", - "section": "64.1 Equivalent of “set-follow-fork-mode” gdb command", - "text": "64.1 Equivalent of “set-follow-fork-mode” gdb command\nThis can be done in two ways:\n\nUse the configuration variable dbg.follow.child to choose the process (parent or child) you want to follow.\nUse dcf to debug until a fork and then use dp to select what process you want to debug.", + "title": "64  Migration from IDA, GDB or WinDBG", + "section": "65.1 Equivalent of “set-follow-fork-mode” gdb command", + "text": "65.1 Equivalent of “set-follow-fork-mode” gdb command\nThis can be done in two ways:\n\nUse the configuration variable dbg.follow.child to choose the process (parent or child) you want to follow.\nUse dcf to debug until a fork and then use dp to select what process you want to debug.", "crumbs": [ "Debugger", - "63  Migration from IDA, GDB or WinDBG" + "64  Migration from IDA, GDB or WinDBG" ] }, { "objectID": "src/debugger/registers.html", "href": "src/debugger/registers.html", - "title": "64  Registers", + "title": "65  Registers", "section": "", "text": "The registers are part of a user area stored in the context structure used by the scheduler. This structure can be manipulated to get and set the values of those registers, and, for example, on Intel hosts, it is possible to directly manipulate DR0-DR7 hardware registers to set hardware breakpoints.\nThere are different commands to get values of registers. For the General Purpose ones use:\n[0x55ca0f427100]> dr\nrax = 0x0000000000000038\nrbx = 0x0000000000000000\nrcx = 0x00007fff03855298\nrdx = 0x00007f52c4ae4080\nr8 = 0x0000000000000000\nr9 = 0x00000000000007f8\nr10 = 0x00007fff03855190\nr11 = 0x0000000000000206\nr12 = 0x000055ca0f427100\nr13 = 0x00007fff03855280\nr14 = 0x0000000000000000\nr15 = 0x0000000000000000\nrsi = 0x00007f52c4b148b8\nrdi = 0x00007f52c4b142e0\nrsp = 0x00007fff03855280\nrbp = 0x0000000000000000\nrip = 0x000055ca0f427100\ncs = 0x0000000000000033\nrflags = 0x0000000000000206\norax = 0xffffffffffffffff\nss = 0x000000000000002b\nfs = 0x00007f52c48c5740\ngs = 0x0000000000000000\nds = 0x0000000000000000\nes = 0x0000000000000000\nfs_base = 0x0000000000000000\ngs_base = 0x0000000000000000\n\n[0x55ca0f427100]> dr rip ; get value of 'rip'\nrip = 0x000055ca0f427100 \n\n[0x4A13B8C0]> dr rip = esp ; set 'rip' as esp\nInteraction between a plugin and the core is done by commands returning Rizin instructions. This is used, for example, to set flags in the core to set values of registers.\n[0x55ca0f427100]> dr* ; Appending '*' will show rizin commands\nar rax = 0x0000000000000038\nar rbx = 0x0000000000000000\nar rcx = 0x00007fff03855298\nar rdx = 0x00007f52c4ae4080\nar r8 = 0x0000000000000000\nar r9 = 0x00000000000007f8\nar r10 = 0x00007fff03855190\nar r11 = 0x0000000000000206\nar r12 = 0x000055ca0f427100\nar r13 = 0x00007fff03855280\nar r14 = 0x0000000000000000\nar r15 = 0x0000000000000000\nar rsi = 0x00007f52c4b148b8\nar rdi = 0x00007f52c4b142e0\nar rsp = 0x00007fff03855280\nar rbp = 0x0000000000000000\nar rip = 0x000055ca0f427100\nar cs = 0x0000000000000033\nar rflags = 0x0000000000000206\nar orax = 0xffffffffffffffff\nar ss = 0x000000000000002b\nar fs = 0x00007f52c48c5740\nar gs = 0x0000000000000000\nar ds = 0x0000000000000000\nar es = 0x0000000000000000\nar fs_base = 0x0000000000000000\nar gs_base = 0x0000000000000000\nAn old copy of registers is stored all the time to keep track of the changes done during execution of a program being analyzed. This old copy can be accessed with oregs.\n[0x55ca0f427100]> dro\nrax = 0x0000000000000038\nrbx = 0x0000000000000000\nrcx = 0x00007fff03855298\nrdx = 0x00007f52c4ae4080\nr8 = 0x0000000000000000\nr9 = 0x00000000000007f8\nr10 = 0x00007fff03855190\nr11 = 0x0000000000000206\nr12 = 0x000055ca0f427100\nr13 = 0x00007fff03855280\nr14 = 0x0000000000000000\nr15 = 0x0000000000000000\nrsi = 0x00007f52c4b148b8\nrdi = 0x00007f52c4b142e0\nrsp = 0x00007fff03855280\nrbp = 0x0000000000000000\nrip = 0x000055ca0f427101\ncs = 0x0000000000000033\nrflags = 0x0000000000000206\norax = 0xffffffffffffffff\nss = 0x000000000000002b\nfs = 0x00007f52c48c5740\ngs = 0x0000000000000000\nds = 0x0000000000000000\nes = 0x0000000000000000\nfs_base = 0x0000000000000000\ngs_base = 0x0000000000000000\nCurrent state of registers\n[0x55ca0f427100]> dr\nrax = 0x0000000000000038\nrbx = 0x0000000000000000\nrcx = 0x00007fff03855298\nrdx = 0x00007f52c4ae4080\nr8 = 0x0000000000000000\nr9 = 0x00000000000007f8\nr10 = 0x00007fff03855190\nr11 = 0x0000000000000206\nr12 = 0x000055ca0f427100\nr13 = 0x00007fff03855280\nr14 = 0x0000000000000000\nr15 = 0x0000000000000000\nrsi = 0x00007f52c4b148b8\nrdi = 0x00007f52c4b142e0\nrsp = 0x00007fff03855280\nrbp = 0x0000000000000000\nrip = 0x000055ca0f427100\ncs = 0x0000000000000033\nrflags = 0x0000000000000206\norax = 0xffffffffffffffff\nss = 0x000000000000002b\nfs = 0x00007f52c48c5740\ngs = 0x0000000000000000\nds = 0x0000000000000000\nes = 0x0000000000000000\nfs_base = 0x0000000000000000\ngs_base = 0x0000000000000000\nValue stored in rip have changed.\nTo store and restore register values you can just dump the output of ’dr*’ command to disk and then re-interpret it again:\n[0x55ca0f427100]> dr* > regs.saved ; save registers\n[0x55ca0f427100]> drp regs.saved ; restore\nEFLAGS can be similarly altered. E.g., setting selected flags:\n[0x55ca0f427100]> dr eflags = pst\n[0x55ca0f427100]> dr eflags = azsti\nYou can get a string which represents latest changes of registers using drd command (diff registers):\n[0x4A13B8C0]> drd\nrip = 0x55ca0f427100 was 0x55ca0f427101 delta 0xffffffffffffffff", "crumbs": [ "Debugger", - "64  Registers" + "65  Registers" ] }, { "objectID": "src/debugger/memory_maps.html", "href": "src/debugger/memory_maps.html", - "title": "65  Memory Maps", + "title": "66  Memory Maps", "section": "", "text": "The ability to understand and manipulate the memory maps of a debugged program is important for many different Reverse Engineering tasks. Rizin offers a rich set of commands to handle memory maps in the binary. This includes listing the memory maps of the currently debugged binary, removing memory maps, handling loaded libraries and more.\nFirst, let’s see the help message for dm, the command which is responsible for handling memory maps:\n[0x55f2104cf620]> dm?\nUsage: dm[?] # Memory map commands\n| dm[j*qt] # List memory maps\n| dm+ <size> # Allocate <size> bytes at current offset\n| dm= # List memory maps of current process with ASCII art bars\n| dm. # Show map name of current address\n| dmm[j*.] # Module memory map commands\n| dm- # Deallocate memory map at current offset\n| dmd[aw] # Dump debug map regions to a file (from-to.dmp)\n| dmh[?] # Glibc heap commands\n| dmi[?] # List/Load symbols\n| dml <file> # Load contents of file into current map region\n| dmp <perms> [<size>] # Change page at current offset with <size>, protection <perms> / Change dbg.map permissions\n to <perms>\n| dmL <size> # Allocate <size> bytes at current offset and promote to huge page\n| dmS[*] [<addr|libname> [<sectname>]] # List sections of target lib\n| dmw[jb?] # Windows heap commands\n| dmx[?] # Jemalloc heap commands\nIn this chapter, we’ll go over some of the most useful subcommands of dm using simple examples. For the following examples, we’ll use a simple hello_world for Linux, but it’ll be the same for every binary.\nFirst things first - open a program in debugging mode:\n$ rizin -d hello_world\nProcess with PID 4760 started...\n[0x7f12fa1debb0]>\n\nNote that we passed “hello_world” to rizin without “./”. rizin will try to find this program in the current directory and then in $PATH, even if no “./” is passed. This is contradictory with UNIX systems, but makes the behaviour consistent for Windows users\n\nLet’s use dm to print the memory maps of the binary we’ve just opened:\n[0x7f133f022fb0]> dm\n0x000055ca0f426000 - 0x000055ca0f427000 - usr 4K s r-- /tmp/hello_world /tmp/hello_world ; tmp_hello_world.r\n0x000055ca0f427000 - 0x000055ca0f428000 - usr 4K s r-x /tmp/hello_world /tmp/hello_world ; tmp_hello_world.r_x\n0x000055ca0f428000 - 0x000055ca0f429000 - usr 4K s r-- /tmp/hello_world /tmp/hello_world ; tmp_hello_world.r.55ca0f428000\n0x000055ca0f429000 - 0x000055ca0f42b000 - usr 8K s rw- /tmp/hello_world /tmp/hello_world ; tmp_hello_world.rw\n0x00007f52c4ae0000 - 0x00007f52c4ae1000 - usr 4K s r-- /usr/lib64/ld-linux-x86-64.so.2 /usr/lib64/ld-linux-x86-64.so.2 ; usr_lib64_ld_linux_x86_64.so.2.r\n0x00007f52c4ae1000 - 0x00007f52c4b06000 * usr 148K s r-x /usr/lib64/ld-linux-x86-64.so.2 /usr/lib64/ld-linux-x86-64.so.2 ; usr_lib64_ld_linux_x86_64.so.2.r_x\n0x00007f52c4b06000 - 0x00007f52c4b11000 - usr 44K s r-- /usr/lib64/ld-linux-x86-64.so.2 /usr/lib64/ld-linux-x86-64.so.2 ; usr_lib64_ld_linux_x86_64.so.2.r.7f52c4b06000\n0x00007f52c4b11000 - 0x00007f52c4b15000 - usr 16K s rw- /usr/lib64/ld-linux-x86-64.so.2 /usr/lib64/ld-linux-x86-64.so.2 ; usr_lib64_ld_linux_x86_64.so.2.rw\n0x00007fff03836000 - 0x00007fff03858000 - usr 136K s rw- [stack] [stack] ; stack_.rw\n0x00007fff038bc000 - 0x00007fff038c0000 - usr 16K s r-- [vvar] [vvar] ; vvar_.r\n0x00007fff038c0000 - 0x00007fff038c2000 - usr 8K s r-x [vdso] [vdso] ; vdso_.r_x\n0xffffffffff600000 - 0xffffffffff601000 - usr 4K s --x [vsyscall] [vsyscall] ; vsyscall_.__x\nFor those of you who prefer a more visual way, you can use dm= to see the memory maps using an ASCII-art bars. This will be handy when you want to see how these maps are located in the memory.\n[0x7f52c4afbbb0]> dm=\nmap 4K - 0x00007f52c4ae0000 |------------------------------| 0x00007f52c4ae1000 r-- /usr/lib64/ld-linux-x86-64.so.2\nmap 148K * 0x00007f52c4ae1000 |------------------------------| 0x00007f52c4b06000 r-x /usr/lib64/ld-linux-x86-64.so.2\nmap 44K - 0x00007f52c4b06000 |------------------------------| 0x00007f52c4b11000 r-- /usr/lib64/ld-linux-x86-64.so.2\nmap 16K - 0x00007f52c4b11000 |------------------------------| 0x00007f52c4b15000 rw- /usr/lib64/ld-linux-x86-64.so.2\nmap 4K - 0xffffffffff600000 |------------------------------| 0xffffffffff601000 --x [vsyscall]\nmap 136K - 0x00007fff03836000 |------------------------------| 0x00007fff03858000 rw- [stack]\nmap 16K - 0x00007fff038bc000 |------------------------------| 0x00007fff038c0000 r-- [vvar]\nmap 8K - 0x00007fff038c0000 |------------------------------| 0x00007fff038c2000 r-x [vdso]\nmap 4K - 0x000055ca0f426000 |#######-----------------------| 0x000055ca0f427000 r-- /tmp/hello_world\nmap 4K - 0x000055ca0f427000 |------#######-----------------| 0x000055ca0f428000 r-x /tmp/hello_world\nmap 4K - 0x000055ca0f428000 |------------#######-----------| 0x000055ca0f429000 r-- /tmp/hello_world\nmap 8K - 0x000055ca0f429000 |------------------############| 0x000055ca0f42b000 rw- /tmp/hello_world\nIf you want to know the memory-map you are currently in, use dm.:\n[0x7f52c4afbbb0]> dm.\n0x00007f52c4ae1000 - 0x00007f52c4b06000 * usr 148K s r-x /usr/lib64/ld-linux-x86-64.so.2 /usr/lib64/ld-linux-x86-64.so.2 ; usr_lib64_ld_linux_x86_64.so.2.r_x\nUsing dmm we can “List modules (libraries, binaries loaded in memory)”, this is quite a handy command to see which modules were loaded.\n[0x7f52c4afbbb0]> dmm\n0x55ca0f426000 0x55ca0f427000 /tmp/hello_world\n0x7f52c4ae0000 0x7f52c4ae1000 /usr/lib64/ld-linux-x86-64.so.2\n\nNote that the output of dm subcommands, and dmm specifically, might be different in various systems and different binaries.\n\nWe can see that along with our hello_world binary itself, another library was loaded which is ld-linux-x86-64.so.2. We don’t see libc yet and this is because Rizin breaks before libc is loaded to memory. Let’s use dcu (debug continue until) to execute our program until the entry point of the program, which Rizin flags as entry0:\n[0x7f52c4afbbb0]> dcu entry0\nContinue until 0x55ca0f427100\nhit breakpoint at: 0x55ca0f427100\n\n[0x55ca0f427100]> dmm\n0x55ca0f426000 0x55ca0f427000 /tmp/hello_world\n0x7f52c48c8000 0x7f52c48ec000 /usr/lib64/libc.so.6\n0x7f52c4ae0000 0x7f52c4ae1000 /usr/lib64/ld-linux-x86-64.so.2\nNow we can see that libc.so.6 was loaded as well, great!\nSpeaking of libc, a popular task for binary exploitation is to find the address of a specific symbol in a library. With this information in hand, you can build, for example, an exploit which uses ROP. This can be achieved using the dmi command. So if we want, for example, to find the address of system() in the loaded libc, we can simply execute the following command:\n[0x55ca0f427100]> dmi libc system\n[Symbols]\nnth paddr vaddr bind type size lib name \n---------------------------------------------------------\n1052 0x0004d2f0 0x7f52c49152f0 WEAK FUNC 45 system\nSimilar to the dm. command, with dmi. you can see the closest symbol to the current address:\n[0x55ca0f427100]> dmi. libc system\n[Symbols]\nnth paddr vaddr bind type size lib name \n------------------------------------------------------\n20 ---------- 0x00004018 GLOBAL NOTYPE 0 _end\nAnother useful command is to list the sections of a specific library. In the following example we’ll list the sections of ld-linux-x86-64.so.2:\n[0x55ca0f427100]> dmS ld-linux-x86-64.so.2\n[Sections]\npaddr size vaddr vsize align perm name type flags \n--------------------------------------------------------------------------------------------------------------------\n0x00000000 0x0 ---------- 0x0 0x0 ---- ld-linux-x86-64.so.2. NULL \n0x00000270 0x1e8 0x7f52c4ae0270 0x1e8 0x0 -r-- ld-linux-x86-64.so.2..gnu.hash GNU_HASH alloc\n0x00000458 0x3c0 0x7f52c4ae0458 0x3c0 0x0 -r-- ld-linux-x86-64.so.2..dynsym DYNSYM alloc\n0x00000818 0x2ca 0x7f52c4ae0818 0x2ca 0x0 -r-- ld-linux-x86-64.so.2..dynstr STRTAB alloc\n0x00000ae2 0x50 0x7f52c4ae0ae2 0x50 0x0 -r-- ld-linux-x86-64.so.2..gnu.version VERSYM alloc\n0x00000b38 0xec 0x7f52c4ae0b38 0xec 0x0 -r-- ld-linux-x86-64.so.2..gnu.version_d VERDEF alloc\n0x00000c28 0x18 0x7f52c4ae0c28 0x18 0x0 -r-- ld-linux-x86-64.so.2..rela.dyn RELA alloc\n0x00000c40 0x18 0x7f52c4ae0c40 0x18 0x0 -r-- ld-linux-x86-64.so.2..relr.dyn NUM alloc\n0x00001000 0x24ebb 0x7f52c4ae1000 0x24ebb 0x0 -r-x ld-linux-x86-64.so.2..text PROGBITS alloc,execute\n0x00026000 0x64e8 0x7f52c4b06000 0x64e8 0x0 -r-- ld-linux-x86-64.so.2..rodata PROGBITS alloc\n0x0002c4e8 0x9a4 0x7f52c4b0c4e8 0x9a4 0x0 -r-- ld-linux-x86-64.so.2..eh_frame_hdr PROGBITS alloc\n0x0002ce90 0x36f8 0x7f52c4b0ce90 0x36f8 0x0 -r-- ld-linux-x86-64.so.2..eh_frame PROGBITS alloc\n0x00030588 0x40 0x7f52c4b10588 0x40 0x0 -r-- ld-linux-x86-64.so.2..note.gnu.property NOTE alloc\n0x000312e0 0x1ba0 0x7f52c4b112e0 0x1ba0 0x0 -rw- ld-linux-x86-64.so.2..data.rel.ro PROGBITS write,alloc\n0x00032e80 0x170 0x7f52c4b12e80 0x170 0x0 -rw- ld-linux-x86-64.so.2..dynamic DYNAMIC write,alloc\n0x00033000 0x1104 0x7f52c4b13000 0x1104 0x0 -rw- ld-linux-x86-64.so.2..data PROGBITS write,alloc\n0x00034104 0x0 0x7f52c4b14110 0x1d0 0x0 -rw- ld-linux-x86-64.so.2..bss NOBITS write,alloc\n0x00034104 0x33 ---------- 0x33 0x0 ---- ld-linux-x86-64.so.2..comment PROGBITS merge,strings\n0x00034138 0x40f8 ---------- 0x40f8 0x0 ---- ld-linux-x86-64.so.2..symtab SYMTAB \n0x00038230 0x23f4 ---------- 0x23f4 0x0 ---- ld-linux-x86-64.so.2..strtab STRTAB \n0x0003a624 0xc8 ---------- 0xc8 0x0 ---- ld-linux-x86-64.so.2..shstrtab STRTAB", "crumbs": [ "Debugger", - "65  Memory Maps" + "66  Memory Maps" ] }, { "objectID": "src/debugger/heap.html", "href": "src/debugger/heap.html", - "title": "66  Heap", + "title": "67  Heap", "section": "", "text": "rizin’s dm subcommands can also display a map of the heap which is useful for those who are interested in inspecting the heap and its content. Simply execute dmh to show a map of the heap:\n[0x55c392ae1189]> dmh\nArena @ 0x7f10940c1b80\nChunk(status=free, addr=0x55c3934c9290, size=0x50, flags=PREV_INUSE)\nChunk(status=allocated, addr=0x55c3934c92e0, size=0x90, flags=PREV_INUSE)\nChunk(status=free, addr=0x55c3934c9370, size=0x20c90, flags=PREV_INUSE)[top][brk_start: 0x55c3934c9000, brk_end: 0x55c3934ea000]]\nYou can also see a graph layout of the heap:\n[0x7fae46236ca6]> dmhg\nArena @ 0x7f10940c1b80\nHeap Layout\n┌────────────────────────────────────┐\n│ Malloc chunk @ 0x55c3934c9290 │\n│ size: 0x50 status: free │\n└────────────────────────────────────┘\n v\n │\n │\n┌────────────────────────────────────┐\n│ Malloc chunk @ 0x55c3934c92e0 │\n│ size: 0x90 status: allocated │\n└────────────────────────────────────┘\n v\n │\n └──┐\n │\n ┌───────────────────────────────┐\n │ Top chunk @ 0x55c3934c9370 │\n └───────────────────────────────┘\nTo get information about bins of the main arena use the dmhd command.\n[0x55c392ae1189]> dmhd\nTcache bins in Main Arena @ 0x7f10940c1b80\nTcache_bin[03] Items: 1\n -> Chunk(addr=0x55c3934c9290, size=0x50, flags=PREV_INUSE)\n\nFast bins in Arena @ 0x7f10940c1b80\nFast_bin[01] [size: 0x20] Empty bin\nFast_bin[02] [size: 0x30] Empty bin\nFast_bin[03] [size: 0x40] Empty bin\nFast_bin[04] [size: 0x50] Empty bin\nFast_bin[05] [size: 0x60] Empty bin\nFast_bin[06] [size: 0x70] Empty bin\nFast_bin[07] [size: 0x80] Empty bin\n\nUnsorted bin in Arena @ 0x7f10940c1b80\nFound 0 chunks in unsorted bin\n\nSmall bins in Arena @ 0x7f10940c1b80\nFound 0 chunks in 0 small bins\n\nLarge bins in Arena @ 0x7f10940c1b80\nFound 0 chunks in 0 large bins\nOther heap commands can be found under dmh, check dmh? for the full list.\n[0x00000000]> dmh?\nUsage: dmh[?] # Glibc heap commands\n| dmh[j*l] [<malloc_state>] # List heap chunks of an arena\n| dmha # List all the arenas\n| dmhb[?] [<bin_num|bin_num:malloc_state>] # Display double linked list for bins in an arena. Use dmhbg command for\n graphical representation.\n| dmhc # Get info about heap chunk at current offset\n| dmhd[j] [<bin_type>] # Display state of bins in an arena. <bin_type> can be tcache/fast/unsorted/small/large\n| dmhf[?] [<fastbin_num|fastbin_num:malloc_state>] # Display all parsed fastbins of main_arena's or a particular arena\n fastbinY instance\n| dmhg [<malloc_state>] # Display heap graph of a particular arena\n| dmhi [<malloc_state>] # Display heap_info structure/structures for a given arena\n| dmhm[*] [<malloc_state>] # List all elements of struct malloc_state\n| dmht # Display all parsed thread cache bins of all arena's tcache instance\nRizin supports Glibc, Jemalloc < 5.0 and Windows heap.", "crumbs": [ "Debugger", - "66  Heap" + "67  Heap" ] }, { "objectID": "src/debugger/files.html", "href": "src/debugger/files.html", - "title": "67  Files", + "title": "68  Files", "section": "", "text": "The Rizin debugger allows the user to list and manipulate the file descriptors from the target process.\nThis is a useful feature, which is not found in other debuggers, the functionality is similar to the lsof command line tool, but have extra subcommands to change the seek, close or duplicate them.\nSo, at any time in the debugging session you can replace the stdio file descriptors to use network sockets created by Rizin, or replace a network socket connection to hijack it.", "crumbs": [ "Debugger", - "67  Files" + "68  Files" ] }, { "objectID": "src/debugger/revdebug.html", "href": "src/debugger/revdebug.html", - "title": "68  Reverse Debugging", + "title": "69  Reverse Debugging", "section": "", "text": "Rizin has reverse debugger, that can seek the program counter backward (e.g. reverse-next, reverse-continue in gdb). Firstly you need to save program state at the point that you want to start recording. The syntax for recording is:\n[0x004028a0]> dts+\nYou can use dts commands for recording and managing program states. After recording the states, you can seek pc back and forth to any points after saved address. So after recording, you can try single step back:\n[0x004028a0]> 2dso\n[0x004028a0]> dr rip\n0x004028ae\n[0x004028a0]> dsb\ncontinue until 0x004028a2\nhit breakpoint at: 4028a2\n[0x004028a0]> dr rip\n0x004028a2\nWhen you run dsb, reverse debugger restore previous recorded state and execute program from it until desired point.\nOr you can also try to continue back:\n[0x004028a0]> db @ 0x004028a2\n[0x004028a0]> 10dso\n[0x004028a0]> dr rip\n0x004028b9\n[0x004028a0]> dcb\n[0x004028a0]> dr rip\n0x004028a2\ndcb seeks program counter until hit the latest breakpoint. So once set a breakpoint, you can back to it any time.\nYou can see current recorded program states using dts:\n[0x004028a0]> dts\nsession: 0 at:0x004028a0 \"\"\nsession: 1 at:0x004028c2 \"\"\nNOTE: Program records can be saved at any moments. These are diff style format that save only different memory area from previous. It saves memory space rather than entire dump.\nYou can leave notes for each records to keep in your mind. dsb and dcb commands restore the program state from latest record if there are many records.\nProgram records can be exported to file and of course imported it. Export/Import records to/from file:\n[0x004028c2]> dtst records_for_test\nSession saved in records_for_test.session and dump in records_for_test.dump\n[0x004028c2]> dtsf records_for_test\nsession: 0, 0x4028a0 diffs: 0\nsession: 1, 0x4028c2 diffs: 0\nMoreover, you can do reverse debugging in ESIL mode. In ESIL mode, program state can be managed by aets commands.\n[0x00404870]> aets+\nAnd step back by aesb:\n[0x00404870]> aer rip\n0x00404870\n[0x00404870]> 5aeso\n[0x00404870]> aer rip\n0x0040487d\n[0x00404870]> aesb\n[0x00404870]> aer rip\n0x00404879\nIn addition to the native reverse debugging capabilities in Rizin, it’s also possible to use gdb’s remote protocol to reverse debug a target gdbserver that supports it. R!dsb and R!dcb are available as dsb and dcb replacements for this purpose, see remote gdb’s documentation for more information.", "crumbs": [ "Debugger", - "68  Reverse Debugging" + "69  Reverse Debugging" ] }, { "objectID": "src/debugger/windows_messages.html", "href": "src/debugger/windows_messages.html", - "title": "69  Windows Messages", + "title": "70  Windows Messages", "section": "", "text": "On Windows, you can use dbW while debugging to set a breakpoint for the message handler of a specific window.\nGet a list of the current process windows with dW :\n[0x7ffe885c1164]> dW\n.----------------------------------------------------.\n| Handle | PID | TID | Class Name |\n)----------------------------------------------------(\n| 0x0023038e | 9432 | 22432 | MSCTFIME UI |\n| 0x0029049e | 9432 | 22432 | IME |\n| 0x002c048a | 9432 | 22432 | Edit |\n| 0x000d0474 | 9432 | 22432 | msctls_statusbar32 |\n| 0x00070bd6 | 9432 | 22432 | Notepad |\n`----------------------------------------------------'\nSet the breakpoint with a message type, together with either the window class name or its handle:\n[0x7ffe885c1164]> dbW WM_KEYDOWN Edit\nBreakpoint set.\nOr\n[0x7ffe885c1164]> dbW WM_KEYDOWN 0x002c048a\nBreakpoint set.\nIf you aren’t sure which window you should put a breakpoint on, use dWi to identify it with your mouse:\n[0x7ffe885c1164]> dWi\nMove cursor to the window to be identified. Ready? y\nTry to get the child? y\n.--------------------------------------------.\n| Handle | PID | TID | Class Name |\n)--------------------------------------------(\n| 0x002c048a | 9432 | 22432 | Edit |\n`--------------------------------------------'", "crumbs": [ "Debugger", - "69  Windows Messages" + "70  Windows Messages" ] }, { "objectID": "src/debugger/apple.html", "href": "src/debugger/apple.html", - "title": "70  macOS/iOS", + "title": "71  macOS/iOS", "section": "", - "text": "70.1 Sign rizin binary\nIf you install the Rizin pkg file and try to use it to debug a binary, you will very likely get an error message such as:\nThis is because the Darwin kernel will refuse to allow rizin to debug another process if you don’t have special rights (or if you are not root).\nTo sign the binary and give it the special rights to allow debugging as a regular user, download the Entitlements file here. Then execute the following command:\nHowever, be aware that even with a signed rizin binary you cannot debug binaries signed by Apple. To bypass the problem you have a few options:", + "text": "71.1 Sign rizin binary\nIf you install the Rizin pkg file and try to use it to debug a binary, you will very likely get an error message such as:\nThis is because the Darwin kernel will refuse to allow rizin to debug another process if you don’t have special rights (or if you are not root).\nTo sign the binary and give it the special rights to allow debugging as a regular user, download the Entitlements file here. Then execute the following command:\nHowever, be aware that even with a signed rizin binary you cannot debug binaries signed by Apple. To bypass the problem you have a few options:", "crumbs": [ "Debugger", - "70  macOS/iOS" + "71  macOS/iOS" ] }, { "objectID": "src/debugger/apple.html#sign-rizin-binary", "href": "src/debugger/apple.html#sign-rizin-binary", - "title": "70  macOS/iOS", + "title": "71  macOS/iOS", "section": "", "text": "Child killed\nptrace: Cannot attach: Invalid argument\n\nPlease ensure your rizin binary is signed and it has the right entitlements\nto make debugger work. Be aware that binaries signed by Apple cannot be\ndebugged due to the Apple System Integrity Protection (SIP).\n\nFor more info look at: https://book.rizin.re/debugger/apple.html#sign-rizin-binary\n\n\n$ codesign --entitlements <entitlements-file> --force -s - $(which rizin)\n\n\nRemove the certificate of the debuggee, by using codesign --remove-signature <binary> or other alternatives like unsign. WARNING: this cannot be undone, so we suggest to make a copy of the original binary.\nDisable SIP with csrutil enable --without debug in Recovery Mode.", "crumbs": [ "Debugger", - "70  macOS/iOS" + "71  macOS/iOS" ] }, { "objectID": "src/debugger/apple.html#debugging-on-macos-over-ssh", "href": "src/debugger/apple.html#debugging-on-macos-over-ssh", - "title": "70  macOS/iOS", - "section": "70.2 Debugging on macOS over SSH", - "text": "70.2 Debugging on macOS over SSH\nIf you are trying to debug a program over SSH, you may experience failures like Rizin getting stuck while opening the file. This is because the OS is waiting for user authentication to allow debugging. However, since you are over SSH, the OS has no way of showing the permission window.\nTo avoid this problem you can either run rizin with sudo or you may instruct taskport to not authenticate the user by executing the following commands. This will disable the debugging authentication prompt even after you reboot.\nsecurity authorizationdb read system.privilege.taskport > taskport.plist\n/usr/libexec/PlistBuddy -c 'Set :authenticate-user false' ./taskport.plist\nsudo security authorizationdb write system.privilege.taskport < taskport.plist", + "title": "71  macOS/iOS", + "section": "71.2 Debugging on macOS over SSH", + "text": "71.2 Debugging on macOS over SSH\nIf you are trying to debug a program over SSH, you may experience failures like Rizin getting stuck while opening the file. This is because the OS is waiting for user authentication to allow debugging. However, since you are over SSH, the OS has no way of showing the permission window.\nTo avoid this problem you can either run rizin with sudo or you may instruct taskport to not authenticate the user by executing the following commands. This will disable the debugging authentication prompt even after you reboot.\nsecurity authorizationdb read system.privilege.taskport > taskport.plist\n/usr/libexec/PlistBuddy -c 'Set :authenticate-user false' ./taskport.plist\nsudo security authorizationdb write system.privilege.taskport < taskport.plist", "crumbs": [ "Debugger", - "70  macOS/iOS" + "71  macOS/iOS" ] }, { "objectID": "src/remote_access/remoting_capabilities.html", "href": "src/remote_access/remoting_capabilities.html", - "title": "71  Remote Access Capabilities", + "title": "72  Remote Access Capabilities", "section": "", "text": "Rizin can be run locally, or it can be started as a server process which is controlled by a local rizin process. This is possible because everything uses Rizin’s IO subsystem which abstracts access to system(), cmd() and all basic IO operations so to work over a network.\nHelp for commands useful for remote access to rizin:\n[0x00000000]> R?\nUsage: R[?] # Connect with other instances of rizin\n| R [[<fd>] <cmd>] # List all open connections / Exec <cmd> at remote <fd>\n| R< [<fd> <cmd>] # Send output of local <cmd> to remote <fd>\n| R![<cmd>] # Run <cmd> via rz_io_system\n| R+ <[proto://]host:port> # Connect to remote host:port\n| R- [<fd>] # remove all hosts or host 'fd'\n| R= <fd> # Open remote session with host 'fd', 'q' to quit\n| R!= <fd>=0 # Enable remote cmd mode, sending commands to remote <fd> server\n| R=! # Disable remote cmd mode\n| Rr <[host:]port> [<cmd>] # Start the rap server (o rap://9999) / Execute <cmd> on rap server\n| Rg[?] # Start the gdbserver\n| Rh[?] # Start the http webserver\n| RH[?] # Start the http webserver (and launch the web browser)\n| Rt <[host:]port> [<cmd>] # Start the tcp server\n| R&r <port> # Start rap server in background (same as '& Rr')\nYou can learn rizin remote capabilities by displaying the list of supported IO plugins: rizin -L.\nA little example should make this clearer. A typical remote session might look like this:\nAt the remote host1:\n$ rizin rap://:1234\nAt the remote host2:\n$ rizin rap://:1234\nAt localhost:\n$ rizin =\nAdd hosts\n[0x004048c5]> R+ rap://<host1>:1234//bin/ls\nConnected to: <host1> at port 1234\nwaiting... ok\n\n[0x004048c5]> R\n0 - rap://<host1>:1234//bin/ls\nYou can open remote files in debug mode (or using any IO plugin) specifying URI when adding hosts:\n[0x004048c5]> R+ R+ rap://<host2>:1234/dbg:///bin/ls\nConnected to: <host2> at port 1234\nwaiting... ok\n0 - rap://<host1>:1234//bin/ls\n1 - rap://<host2>:1234/dbg:///bin/ls\nTo execute commands on host1:\n[0x004048c5]> R 0 px\n[0x004048c5]> R s 0x666\nTo open a session with host2:\n[0x004048c5]> R= 1\nfd:6> pi 1\n...\nfd:6> q\nTo remove hosts (and close connections):\n[0x004048c5]> R-\nYou can also redirect rizin output to a TCP or UDP server (such as nc -l). First, Add the server with R+ tcp:// or R+ udp://, then you can redirect the output of a command to be sent to the server:\n[0x004048c5]> R+ tcp://<host>:<port>/\nConnected to: <host> at port <port>\n5 - tcp://<host>:<port>/\n[0x004048c5]> R<5 cmd...\nThe R< command will send the output from the execution of cmd to the remote connection number N (or the last one used if no id specified).", "crumbs": [ "Remote Access", - "71  Remote Access Capabilities" + "72  Remote Access Capabilities" ] }, { "objectID": "src/remote_access/remote_gdb.html", "href": "src/remote_access/remote_gdb.html", - "title": "72  Debugging with gdbserver", + "title": "73  Debugging with gdbserver", "section": "", "text": "Rizin allows remote debugging over the gdb remote protocol. So you can run a gdbserver and connect to it with rizin for remote debugging. The syntax for connecting is:\n$ rizin -d gdb://<host>:<port>\nNote that the following command does the same, Rizin will use the debug plugin specified by the uri if found.\n$ rizin -D gdb gdb://<host>:<port>\nThe debug plugin can be changed at runtime using the dL or Ld commands.\nOr if the gdbserver is running in extended mode, you can attach to a process on the host with:\n$ rizin -d gdb://<host>:<port>/<pid>\nIt is also possible to start debugging after analyzing a file using the doof command which rebases the current session’s data after opening gdb\n[0x00404870]> doof gdb://<host>:<port>/<pid>\nAfter connecting, you can use the standard Rizin debug commands as normal.\nRizin does not yet load symbols from gdbserver, so it needs the binary to be locally present to load symbols from it. In case symbols are not loaded even if the binary is present, you can try specifying the path with e dbg.exe.path:\n$ rizin -e dbg.exe.path=<path> -d gdb://<host>:<port>\nIf symbols are loaded at an incorrect base address, you can try specifying the base address too with e bin.baddr:\n$ rizin -e bin.baddr=<baddr> -e dbg.exe.path=<path> -d gdb://<host>:<port>\nUsually the gdbserver reports the maximum packet size it supports. Otherwise, rizin resorts to sensible defaults. But you can specify the maximum packet size with the environment variable R2_GDB_PKTSZ. You can also check and set the max packet size during a session with the IO system, R!.\n$ export R2_GDB_PKTSZ=512\n$ rizin -d gdb://<host>:<port>\n= attach <pid> <tid>\nAssuming filepath <path/to/exe>\n[0x7ff659d9fcc0]> R!pktsz\npacket size: 512 bytes\n[0x7ff659d9fcc0]> R!pktsz 64\n[0x7ff659d9fcc0]> R!pktsz\npacket size: 64 bytes\nThe gdb IO system provides useful commands which might not fit into any standard rizin commands. You can get a list of these commands with R!?. (Remember, R! accesses the underlying IO plugin’s system()).\n[0x7ff659d9fcc0]> R!?\nUsage: R!cmd args\n R!pid - show targeted pid\n R!pkt s - send packet 's'\n R!monitor cmd - hex-encode monitor command and pass to target interpreter\n R!rd - show reverse debugging availability\n R!dsb - step backwards\n R!dcb - continue backwards\n R!detach [pid] - detach from remote/detach specific pid\n R!inv.reg - invalidate reg cache\n R!pktsz - get max packet size used\n R!pktsz bytes - set max. packet size as 'bytes' bytes\n R!exec_file [pid] - get file which was executed for current/specified pid\nNote that R!dsb and R!dcb are only available in special gdbserver implementations such as Mozilla’s rr, the default gdbserver doesn’t include remote reverse debugging support. Use R!rd to print the currently available reverse debugging capabilities.\nIf you are interested in debugging rizin’s interaction with gdbserver you can use R!monitor set remote-debug 1 to turn on logging of gdb’s remote protocol packets in gdbserver’s console and R!monitor set debug 1 to show general debug messages from gdbserver in its console.\nrizin also provides its own gdbserver implementation:\n$ rizin =\n[0x00000000]> Rg?\nUsage: R[g] [...] # gdb server\ngdbserver:\n| Rg port file [args] listen on 'port' debugging 'file' using gdbserver\n| Rg! port file [args] same as above, but debug protocol messages (like gdbserver --remote-debug)\nSo you can start it as:\n$ rizin =\n[0x00000000]> Rg 8000 /bin/rizin -\nAnd then connect to it like you would to any gdbserver. For example, with rizin:\n$ rizin -d gdb://localhost:8000", "crumbs": [ "Remote Access", - "72  Debugging with gdbserver" + "73  Debugging with gdbserver" ] }, { "objectID": "src/remote_access/windbg.html", "href": "src/remote_access/windbg.html", - "title": "73  WinDBG Kernel-mode Debugging (KD)", + "title": "74  WinDBG Kernel-mode Debugging (KD)", "section": "", - "text": "73.1 Setting Up KD on Windows\nThe WinDBG KD interface support for Rizin allows you to attach to VM running Windows and debug its kernel over a serial port or network.\nIt is also possible to use the remote GDB interface to connect and debug Windows kernels without depending on Windows capabilities.\nBear in mind that WinDBG KD support is still work-in-progress, and this is just an initial implementation which will get better in time.", + "text": "74.1 Setting Up KD on Windows\nThe WinDBG KD interface support for Rizin allows you to attach to VM running Windows and debug its kernel over a serial port or network.\nIt is also possible to use the remote GDB interface to connect and debug Windows kernels without depending on Windows capabilities.\nBear in mind that WinDBG KD support is still work-in-progress, and this is just an initial implementation which will get better in time.", "crumbs": [ "Remote Access", - "73  WinDBG Kernel-mode Debugging (KD)" + "74  WinDBG Kernel-mode Debugging (KD)" ] }, { "objectID": "src/remote_access/windbg.html#setting-up-kd-on-windows", "href": "src/remote_access/windbg.html#setting-up-kd-on-windows", - "title": "73  WinDBG Kernel-mode Debugging (KD)", + "title": "74  WinDBG Kernel-mode Debugging (KD)", "section": "", - "text": "For a complete walkthrough, refer to Microsoft’s documentation.\n\n\n73.1.1 Serial Port\nEnable KD over a serial port on Windows Vista and higher like this:\nbcdedit /debug on\nbcdedit /dbgsettings serial debugport:1 baudrate:115200\nOr like this for Windows XP:\nOpen boot.ini and add /debug /debugport=COM1 /baudrate=115200:\n[boot loader]\ntimeout=30\ndefault=multi(0)disk(0)rdisk(0)partition(1)\\WINDOWS\n[operating systems]\nmulti(0)disk(0)rdisk(0)partition(1)\\WINDOWS=\"Debugging with Cable\" /fastdetect /debug /debugport=COM1 /baudrate=57600\nIn case of VMWare\nVirtual Machine Settings -> Add -> Serial Port\nDevice Status:\n[v] Connect at power on\nConnection:\n[v] Use socket (named pipe)\n[_/tmp/winkd.pipe________]\nFrom: Server To: Virtual Machine\nConfigure the VirtualBox Machine like this:\nPreferences -> Serial Ports -> Port 1\n\n[v] Enable Serial Port\nPort Number: [_COM1_______[v]]\nPort Mode: [_Host_Pipe__[v]]\n [v] Create Pipe\nPort/File Path: [_/tmp/winkd.pipe____]\nOr just spawn the VM with qemu like this:\n$ qemu-system-x86_64 -chardev socket,id=serial0,\\\n path=/tmp/winkd.pipe,nowait,server \\\n -serial chardev:serial0 -hda Windows7-VM.vdi\n\n\n73.1.2 Network\nEnable KD over network (KDNet) on Windows 7 or later likes this:\nbcdedit /debug on\nbcdedit /dbgsettings net hostip:w.x.y.z port:n\nStarting from Windows 8 there is no way to enforce debugging for every boot, but it is possible to always show the advanced boot options, which allows to enable kernel debugging:\nbcedit /set {globalsettings} advancedoptions true", + "text": "For a complete walkthrough, refer to Microsoft’s documentation.\n\n\n74.1.1 Serial Port\nEnable KD over a serial port on Windows Vista and higher like this:\nbcdedit /debug on\nbcdedit /dbgsettings serial debugport:1 baudrate:115200\nOr like this for Windows XP:\nOpen boot.ini and add /debug /debugport=COM1 /baudrate=115200:\n[boot loader]\ntimeout=30\ndefault=multi(0)disk(0)rdisk(0)partition(1)\\WINDOWS\n[operating systems]\nmulti(0)disk(0)rdisk(0)partition(1)\\WINDOWS=\"Debugging with Cable\" /fastdetect /debug /debugport=COM1 /baudrate=57600\nIn case of VMWare\nVirtual Machine Settings -> Add -> Serial Port\nDevice Status:\n[v] Connect at power on\nConnection:\n[v] Use socket (named pipe)\n[_/tmp/winkd.pipe________]\nFrom: Server To: Virtual Machine\nConfigure the VirtualBox Machine like this:\nPreferences -> Serial Ports -> Port 1\n\n[v] Enable Serial Port\nPort Number: [_COM1_______[v]]\nPort Mode: [_Host_Pipe__[v]]\n [v] Create Pipe\nPort/File Path: [_/tmp/winkd.pipe____]\nOr just spawn the VM with qemu like this:\n$ qemu-system-x86_64 -chardev socket,id=serial0,\\\n path=/tmp/winkd.pipe,nowait,server \\\n -serial chardev:serial0 -hda Windows7-VM.vdi\n\n\n74.1.2 Network\nEnable KD over network (KDNet) on Windows 7 or later likes this:\nbcdedit /debug on\nbcdedit /dbgsettings net hostip:w.x.y.z port:n\nStarting from Windows 8 there is no way to enforce debugging for every boot, but it is possible to always show the advanced boot options, which allows to enable kernel debugging:\nbcedit /set {globalsettings} advancedoptions true", "crumbs": [ "Remote Access", - "73  WinDBG Kernel-mode Debugging (KD)" + "74  WinDBG Kernel-mode Debugging (KD)" ] }, { "objectID": "src/remote_access/windbg.html#connecting-to-kd-interface-on-rizin", "href": "src/remote_access/windbg.html#connecting-to-kd-interface-on-rizin", - "title": "73  WinDBG Kernel-mode Debugging (KD)", - "section": "73.2 Connecting to KD interface on rizin", - "text": "73.2 Connecting to KD interface on rizin\n\n73.2.1 Serial Port\nRizin will use the winkd io plugin to connect to a socket file created by virtualbox or qemu. Also, the winkd debugger plugin and we should specify the x86-32 too. (32 and 64 bit debugging is supported)\n$ rizin -a x86 -b 32 -D winkd winkd:///tmp/winkd.pipe\nOn Windows you should run the following line:\n$ rizin -D winkd winkd://\\\\.\\pipe\\com_1\n\n\n73.2.2 Network\n$ rizin -a x86 -b 32 -d winkd://<hostip>:<port>:w.x.y.z", + "title": "74  WinDBG Kernel-mode Debugging (KD)", + "section": "74.2 Connecting to KD interface on rizin", + "text": "74.2 Connecting to KD interface on rizin\n\n74.2.1 Serial Port\nRizin will use the winkd io plugin to connect to a socket file created by virtualbox or qemu. Also, the winkd debugger plugin and we should specify the x86-32 too. (32 and 64 bit debugging is supported)\n$ rizin -a x86 -b 32 -D winkd winkd:///tmp/winkd.pipe\nOn Windows you should run the following line:\n$ rizin -D winkd winkd://\\\\.\\pipe\\com_1\n\n\n74.2.2 Network\n$ rizin -a x86 -b 32 -d winkd://<hostip>:<port>:w.x.y.z", "crumbs": [ "Remote Access", - "73  WinDBG Kernel-mode Debugging (KD)" + "74  WinDBG Kernel-mode Debugging (KD)" ] }, { "objectID": "src/remote_access/windbg.html#using-kd", "href": "src/remote_access/windbg.html#using-kd", - "title": "73  WinDBG Kernel-mode Debugging (KD)", - "section": "73.3 Using KD", - "text": "73.3 Using KD\nWhen connecting to a KD interface, Rizin will send a breakin packet to interrupt the target, and we will get stuck here:\n[0x828997b8]> pd 20\n ;-- eip:\n 0x828997b8 cc int3\n 0x828997b9 c20400 ret 4\n 0x828997bc cc int3\n 0x828997bd 90 nop\n 0x828997be c3 ret\n 0x828997bf 90 nop\nIn order to skip that trap we will need to change eip and run ‘dc’ twice:\ndr eip=eip+1\ndc\ndr eip=eip+1\ndc\nNow the Windows VM will be interactive again. We will need to kill rizin and attach again to get back to control the kernel.\nIn addition, the dp command can be used to list all processes, and dpa or dp= to attach to the process. This will display the base address of the process in the physical memory layout.", + "title": "74  WinDBG Kernel-mode Debugging (KD)", + "section": "74.3 Using KD", + "text": "74.3 Using KD\nWhen connecting to a KD interface, Rizin will send a breakin packet to interrupt the target, and we will get stuck here:\n[0x828997b8]> pd 20\n ;-- eip:\n 0x828997b8 cc int3\n 0x828997b9 c20400 ret 4\n 0x828997bc cc int3\n 0x828997bd 90 nop\n 0x828997be c3 ret\n 0x828997bf 90 nop\nIn order to skip that trap we will need to change eip and run ‘dc’ twice:\ndr eip=eip+1\ndc\ndr eip=eip+1\ndc\nNow the Windows VM will be interactive again. We will need to kill rizin and attach again to get back to control the kernel.\nIn addition, the dp command can be used to list all processes, and dpa or dp= to attach to the process. This will display the base address of the process in the physical memory layout.", "crumbs": [ "Remote Access", - "73  WinDBG Kernel-mode Debugging (KD)" + "74  WinDBG Kernel-mode Debugging (KD)" ] }, { "objectID": "src/remote_access/windbg.html#using-the-plugin", "href": "src/remote_access/windbg.html#using-the-plugin", - "title": "73  WinDBG Kernel-mode Debugging (KD)", - "section": "74.1 Using the plugin", - "text": "74.1 Using the plugin\nTo use the windbg plugin, pass the same command-line options as you would for WinDBG or kd (see Microsoft’s documentation), quoting/escaping when necessary:\n> rizin -d \"windbg://-remote tcp:server=Server,port=Socket\"\n\n> rizin -d \"windbg://MyProgram.exe \\\"my arg\\\"\"\n\n> rizin -d \"windbg://-k net:port=<n>,key=<MyKey>\"\n\n> rizin -d \"windbg://-z MyDumpFile.dmp\"\nYou can then debug normally (see d? command) or interact with the backend shell directly with the R! command:\n[0x7ffcac9fcea0]> dcu 0x0007ffc98f42190\nContinue until 0x7ffc98f42190 using 1 bpsize\nModLoad: 00007ffc`ab6b0000 00007ffc`ab6e0000 C:\\WINDOWS\\System32\\IMM32.DLL\nBreakpoint 1 hit\nhit breakpoint at: 0x7ffc98f42190\n\n[0x7fffcf232190]> R!k4\nChild-SP RetAddr Call Site\n00000033`73b1f618 00007ff6`c67a861d r_main!r_main_rizin\n00000033`73b1f620 00007ff6`c67d0019 rizin!main+0x8d\n00000033`73b1f720 00007ff6`c67cfebe rizin!invoke_main+0x39\n00000033`73b1f770 00007ff6`c67cfd7e rizin!__scrt_common_main_seh+0x12e", + "title": "74  WinDBG Kernel-mode Debugging (KD)", + "section": "75.1 Using the plugin", + "text": "75.1 Using the plugin\nTo use the windbg plugin, pass the same command-line options as you would for WinDBG or kd (see Microsoft’s documentation), quoting/escaping when necessary:\n> rizin -d \"windbg://-remote tcp:server=Server,port=Socket\"\n\n> rizin -d \"windbg://MyProgram.exe \\\"my arg\\\"\"\n\n> rizin -d \"windbg://-k net:port=<n>,key=<MyKey>\"\n\n> rizin -d \"windbg://-z MyDumpFile.dmp\"\nYou can then debug normally (see d? command) or interact with the backend shell directly with the R! command:\n[0x7ffcac9fcea0]> dcu 0x0007ffc98f42190\nContinue until 0x7ffc98f42190 using 1 bpsize\nModLoad: 00007ffc`ab6b0000 00007ffc`ab6e0000 C:\\WINDOWS\\System32\\IMM32.DLL\nBreakpoint 1 hit\nhit breakpoint at: 0x7ffc98f42190\n\n[0x7fffcf232190]> R!k4\nChild-SP RetAddr Call Site\n00000033`73b1f618 00007ff6`c67a861d r_main!r_main_rizin\n00000033`73b1f620 00007ff6`c67d0019 rizin!main+0x8d\n00000033`73b1f720 00007ff6`c67cfebe rizin!invoke_main+0x39\n00000033`73b1f770 00007ff6`c67cfd7e rizin!__scrt_common_main_seh+0x12e", "crumbs": [ "Remote Access", - "73  WinDBG Kernel-mode Debugging (KD)" + "74  WinDBG Kernel-mode Debugging (KD)" ] }, { "objectID": "src/tools/intro.html", "href": "src/tools/intro.html", - "title": "74  Tools", + "title": "75  Tools", "section": "", "text": "Rizin is not just the only tool provided by the Rizin project. The rest if chapters in this book are focused on explaining the use of the rizin tool, this chapter will focus on explaining all the other companion tools that are shipped inside the Rizin project.\nAll the functionalities provided by the different APIs and plugins have also different tools to allow to use them from the commandline and integrate them with shellscripts easily.\nThanks to the orthogonal design of the framework it is possible to do all the things that Rizin is able from different places:\n\nThese companion tools\nNative library apis\nScripting with rz-pipe\nThe rizin shell", "crumbs": [ "Command Line Tools", - "74  Tools" + "75  Tools" ] }, { "objectID": "src/tools/rz-ax/intro.html", "href": "src/tools/rz-ax/intro.html", - "title": "75  Rz-ax", + "title": "76  Rz-ax", "section": "", "text": "The rz-ax utility comes with the Rizin framework and aims to be a minimalistic expression evaluator for the shell. It is useful for making base conversions between floating point values, hexadecimal representations, hexpair strings to ascii, octal to integer. It supports endianness and can be used as a shell if no arguments are given.\nThis is the help message of rz-ax, this tool can be used in the command-line or interactively (reading the values from stdin), so it can be used as a multi-base calculator.\nInside Rizin, the functionality of rz-ax is available under the % command. For example:\n[0x00000000]> % 3+4\nAs you can see, the numeric expressions can contain mathematical expressions like addition, subtraction, as well as group operations with parenthesis.\nThe syntax in which the numbers are represented define the base, for example:\n\n3 : decimal, base 10\n0xface : hexadecimal, base 16\n0472 : octal, base 8\n2M : units, 2 megabytes\n…\n\nThis is the help message of rz-ax -h, which will show you a bunch more syntaxes\n$ rz-ax -h\nUsage: rz-ax [options] [expr ...]\n =[base] ; rz-ax =10 0x46 -> output in base 10\n int -> hex ; rz-ax 10\n hex -> int ; rz-ax 0xa\n -int -> hex ; rz-ax -77\n -hex -> int ; rz-ax 0xffffffb3\n int -> bin ; rz-ax b30\n int -> ternary ; rz-ax t42\n bin -> int ; rz-ax 1010d\n ternary -> int ; rz-ax 1010dt\n float -> hex ; rz-ax 3.33f\n hex -> float ; rz-ax Fx40551ed8\n oct -> hex ; rz-ax 35o\n hex -> oct ; rz-ax Ox12 (O is a letter)\n bin -> hex ; rz-ax 1100011b\n hex -> bin ; rz-ax Bx63\n ternary -> hex ; rz-ax 212t\n hex -> ternary ; rz-ax Tx23\n raw -> hex ; rz-ax -S < /binfile\n hex -> raw ; rz-ax -s 414141\n -l ; append newline to output (for -E/-D/-r/..\n -a show ascii table ; rz-ax -a\n -b bin -> str ; rz-ax -b 01000101 01110110\n -B str -> bin ; rz-ax -B hello\n -d force integer ; rz-ax -d 3 -> 3 instead of 0x3\n -e swap endianness ; rz-ax -e 0x33\n -D base64 decode ;\n -E base64 encode ;\n -f floating point ; rz-ax -f 6.3+2.1\n -F stdin slurp code hex ; rz-ax -F < shellcode.[c/py/js]\n -h show this help ; rz-ax -h\n -i dump as C byte array ; rz-ax -i < bytes\n -I IP address <-> LONG ; rz-ax -I 3530468537\n -k keep base ; rz-ax -k 33+3 -> 36\n -L bin -> hex(bignum) ; rz-ax -L 111111111 # 0x1ff\n -n int value -> hexpairs; rz-ax -n 0x1234 # 34120000\n -o octalstr -> raw ; rz-ax -o \\162 \\172 # rz\n -N binary number ; rz-ax -N 0x1234 # \\x34\\x12\\x00\\x00\n -r rz style output ; rz-ax -r 0x1234\n -s hexstr -> raw ; rz-ax -s 43 4a 50\n -S raw -> hexstr ; rz-ax -S < /bin/ls > ls.hex\n -t tstamp -> str ; rz-ax -t 1234567890\n -x hash string ; rz-ax -x linux osx\n -u units ; rz-ax -u 389289238 # 317.0M\n -w signed word ; rz-ax -w 16 0xffff\n -v version ; rz-ax -v\n -p position of set bits ; rz-ax -p 0xb3\nSome examples:\n$ rz-ax 3+0x80\n0x83\n\n$ rz-ax 0x80+3\n131\n\n$ echo 0x80+3 | rz-ax\n131\n\n$ rz-ax -s 4142\nAB\n\n$ rz-ax -S AB\n4142\n\n$ rz-ax -S < bin.foo\n...\n\n$ rz-ax -e 33\n0x21000000\n\n$ rz-ax -e 0x21000000\n33\n\n$ rz-ax -K 90203010\n+--[0x10302090]---+\n|Eo. . |\n| . . . . |\n| o |\n| . |\n| S |\n| |\n| |\n| |\n| |\n+-----------------+", "crumbs": [ "Command Line Tools", - "75  Rz-ax" + "76  Rz-ax" ] }, { "objectID": "src/tools/rz-find/intro.html", "href": "src/tools/rz-find/intro.html", - "title": "76  Rz-find", + "title": "77  Rz-find", "section": "", "text": "rz-find is the command line frontend of the rz_search library. Which allows you to search for strings, sequences of bytes with binary masks, etc\n$ rz-find -h\nUsage: rz-find [-mXnzZhqv] [-a align] [-b sz] [-f/t from/to] [-[e|s|w|S|I] str] [-x hex] -|file|dir ..\n -a [align] Only accept aligned hits\n -b [size] Set block size\n -e [regex] Search for regex matches (can be used multiple times)\n -f [from] Start searching from address 'from'\n -F [file] Read the contents of the file and use it as keyword\n -h Show this help\n -i Identify filetype (rizin -nqcpm file)\n -j Output in JSON\n -m Magic search, file-type carver\n -M [str] Set a binary mask to be applied on keywords\n -n Do not stop on read errors\n -r Print using rizin commands\n -s [str] Search for a specific string (can be used multiple times)\n -w [str] Search for a specific wide string (can be used multiple times). Assumes str is UTF-8.\n -I [str] Search for an entry in import table.\n -S [str] Search for a symbol in symbol table.\n -t [to] Stop search at address 'to'\n -q Quiet - do not show headings (filenames) above matching contents (default for searching a single file)\n -v Show version information\n -x [hex] Search for hexpair string (909090) (can be used multiple times)\n -X Show hexdump of search results\n -z Search for zero-terminated strings\n -Z Show string found on each search hit\nThat’s how to use it, first we’ll search for “lib” inside the /bin/ls binary.\n$ rz-find -s lib /usr/bin/ls\n0x319\n0x11f3\n0x13b7\n0x1b5ea\n0x1b792\nNote that the output is pretty minimal, and shows the offsets where the string lib is found. We can then use this output to feed other tools.\nCounting results:\n$ rz-find -s lib /usr/bin/ls | wc -l\n5\nDisplaying results with context:\n$ export F=/usr/bin/ls\n$ for a in `rz-find -s lib $F` ; do \\\n rizin -ns $a -qc'x 32' $F ; done\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\n0x00000319 6c69 6236 342f 6c64 2d6c 696e 7578 2d78 lib64/ld-linux-x\n0x00000329 3836 2d36 342e 736f 2e32 0000 0000 0004 86-64.so.2......\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\n0x000011f3 6c69 6263 5f73 7461 7274 5f6d 6169 6e00 libc_start_main.\n0x00001203 6973 7770 7269 6e74 0073 6967 7072 6f63 iswprint.sigproc\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\n0x000013b7 6c69 6263 2e73 6f2e 3600 474c 4942 435f libc.so.6.GLIBC_\n0x000013c7 4142 495f 4454 5f52 454c 5200 474c 4942 ABI_DT_RELR.GLIB\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\n0x0001b5ea 6c69 6273 2f00 5554 462d 3800 e280 9900 libs/.UTF-8.....\n0x0001b5fa a1af 0022 00a1 0765 00e2 8098 0060 0073 ...\"...e.....`.s\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\n0x0001b792 6c69 622f 7873 7472 746f 6c2e 6300 4153 lib/xstrtol.c.AS\n0x0001b7a2 4349 4900 0000 6361 6e6e 6f74 2064 6574 CII...cannot det\nrz-find can also be used as a replacement of file to identify the mimetype of a file using the internal magic database of Rizin.\n$ rz-find -i /usr/bin/ls\n0x00000000 1 ELF 64-bit LSB shared object, x86-64, version 1\nAlso works as a strings replacement, similar to what you do with rz-bin -z, but without caring about parsing headers and obeying binary sections.\n$ rz-find -z /usr/bin/ls | grep http\n# https://wiki.xiph.org/MIME_Types_and_File_Extensions\n# https://wiki.xiph.org/MIME_Types_and_File_Extensions\nhttps://www.gnu.org/gethelp/\nhttps://www.gnu.org/software/coreutils/\nReport any translation bugs to <https://translationproject.org/team/>\nhttps://gnu.org/licenses/gpl.html", "crumbs": [ "Command Line Tools", - "76  Rz-find" + "77  Rz-find" ] }, { "objectID": "src/tools/rz-run/intro.html", "href": "src/tools/rz-run/intro.html", - "title": "77  Rz-run", + "title": "78  Rz-run", "section": "", "text": "rz-run is a tool allowing to setup a specified execution environment - redefine stdin/stdout, pipes, change the environment variables and other settings useful to craft the boundary conditions you need to run a binary for debugging.\n$ rz-run -h\nUsage: [directives] [script.rz] [--] [program] [args]\n -h Show this help\n -l Show profile options\n -t Output template profile\n -v Show version information\n -w Wait for incoming terminal process\n -- [program] [args] Run commands\nIt takes the text file in key=value format to specify the execution environment. Rz-run can be used as both separate tool or as a part of rizin. To load the rz-run profile in Rizin you need to use either -r to load the profile from file or -R to specify the directive from string.\nThe format of the profile is very simple. Note the most important keys - program and arg*\nOne of the most common usage cases - redirect the output of debugged program in rizin. For this you need to use stdio, stdout, stdin, input, and a couple similar keys.\nHere is the basic profile example:\nprogram=/bin/ls\narg1=/bin\n# arg2=hello\n# arg3=\"hello\\nworld\"\n# arg4=:048490184058104849\n# arg5=:!ragg2 -p n50 -d 10:0x8048123\n# arg6=@arg.txt\n# arg7=@300@ABCD # 300 chars filled with ABCD pattern\n# system=rizin =\n# aslr=no\nsetenv=FOO=BAR\n# unsetenv=FOO\n# clearenv=true\n# envfile=environ.txt\ntimeout=3\n# timeoutsig=SIGTERM # or 15\n# connect=localhost:8080\n# listen=8080\n# pty=false\n# fork=true\n# bits=32\n# pid=0\n# pidfile=/tmp/foo.pid\n# #sleep=0\n# #maxfd=0\n# #execve=false\n# #maxproc=0\n# #maxstack=0\n# #core=false\n# #stdio=blah.txt\n# #stderr=foo.txt\n# stdout=foo.txt\n# stdin=input.txt # or !program to redirect input from another program\n# input=input.txt\n# chdir=/\n# chroot=/mnt/chroot\n# libpath=$PWD:/tmp/lib\n# rzpreload=yes\n# preload=/lib/libfoo.so\n# setuid=2000\n# seteuid=2000\n# setgid=2001\n# setegid=2001\n# nice=5", "crumbs": [ "Command Line Tools", - "77  Rz-run" + "78  Rz-run" ] }, { "objectID": "src/tools/rz-bin/intro.html", "href": "src/tools/rz-bin/intro.html", - "title": "78  Rz-bin — Show Properties of a Binary", + "title": "79  Rz-bin — Show Properties of a Binary", "section": "", - "text": "Rz-bin is a powerful tool to handle binaries, to get information on imports, sections, headers and other data. It can present this information in several formats accepted by other tools, including Rizin itself. rz-bin understands many file formats: Java CLASS, ELF, PE, Mach-O or any format supported by plugins, and it is able to obtain symbol import/exports, library dependencies, strings of data sections, xrefs, entrypoint address, sections, architecture type.\n$ rz-bin -h\nUsage: rz-bin [-AcdeEghHiIjlLMqrRsSUvVxzZ] [-@ at] [-a arch] [-b bits] [-B addr]\n [-C F:C:D] [-f str] [-m addr] [-n str] [-N m:M] [-P pdb]\n [-o str] [-O str] [-k query] [-D lang symname] file\n -@ [addr] Show section, symbol, or import at the given address\n -A List sub-binaries and their arch-bits pairs\n -a [arch] Set arch (x86, arm, .. or <arch>_<bits>)\n -b [bits] Set bits (32, 64 ...)\n -B [addr] Override base address (pie bins)\n -c List classes\n -cc List classes in header format\n -C [fmt:C:D] Create [elf,mach0,pe] with Code and Data hexpairs (see -a)\n -d Show debug/dwarf information\n -dd Load debug/dwarf information from debuginfod server\n -D lang name Demangle symbol name (-D all for bin.demangle=true)z\n -e Entrypoint\n -ee Constructor/destructor entrypoints\n -E Globally exportable symbols\n -f [str] Select sub-bin named str\n -F [binfmt] Force to use that bin plugin (ignore header check)\n -g Same as -SMZIHVResizcld -SS -SSS -ee (show all info)\n -G [addr] Load address . offset to header\n -h Show this help\n -H Header fields\n -i Import (symbols imported from libraries)\n -I Binary info\n -j Output in JSON\n -k [sdb-query] Run sdb query. for example: '*'\n -K [algo] Calculate checksums (md5, sha1, ..)\n -l Linked libraries\n -L [plugin] List supported bin plugins or plugin details\n -m [addr] Show source line at addr\n -M Main (show address of main symbol)\n -n [str] Show section, symbol or import named str\n -N [min:max] Force min:max number of chars per string (see -z and -zz)\n -o [str] Output file/folder for write operations (out by default)\n -O [str] Write/extract operations (-O help)\n -p Show physical addresses\n -P Show debug/pdb information\n -PP Download pdb file for binary\n -q Quiet mode, just show fewer data\n -qq Show less info (no offset/size for -z for ex.)\n -Q Show load address used by dlopen (non-aslr libs)\n -r Show output in rizin format\n -R Show relocations\n -s Symbols\n -S Sections\n -SS Segments\n -SSS Sections mapping to segments\n -T Display file signature\n -u Unfiltered (no rename duplicated symbols/sections)\n -U Resources\n -v Show version information\n -V Show binary version information\n -w Display try/catch blocks\n -x Extract bins contained in file\n -X [fmt] [f] .. Package in fat or zip the given files and bins contained in file\n -Y [fw file] Calculate all the possibles base address candidates of a firmware bin\n -z Show strings (from data section)\n -zz Show strings (from raw strings from bin)\n -zzz Dump raw strings to stdout (for huge files)\n -Z Guess size of binary program\nEnvironment:\n RZ_NOPLUGINS: # do not load shared plugins (speedup loading)\n RZ_BIN_LANG: e bin.lang # assume lang for demangling\n RZ_BIN_DEMANGLE=0:e bin.demangle # do not demangle symbols\n RZ_BIN_MAXSTRBUF: e str.search.buffer_size # specify maximum buffer size\n RZ_BIN_STRFILTER: e bin.str.filter # rizin -qc 'e bin.str.filter=??' -\n RZ_BIN_STRPURGE: e bin.str.purge # try to purge false positives\n RZ_BIN_DEBASE64: e bin.debase64 # try to debase64 all strings\n RZ_BIN_PDBSERVER: e pdb.server # use alternative PDB server\n RZ_BIN_SYMSTORE: e pdb.symstore # path to downstream symbol store\n RZ_BIN_PREFIX: e bin.prefix # prefix symbols/sections/relocs with a specific string\n RZ_BIN_DEBUGINFOD_URLS: e bin.dbginfo.debuginfod_urls # use alternative debuginfod server\n RZ_CONFIG:", + "text": "Rz-bin is a powerful tool to handle binaries, to get information on imports, sections, headers and other data. It can present this information in several formats accepted by other tools, including Rizin itself. rz-bin understands many file formats: Java CLASS, ELF, PE, Mach-O or any format supported by plugins, and it is able to obtain symbol import/exports, library dependencies, strings of data sections, xrefs, entrypoint address, sections, architecture type.\n$ rz-bin -h\nUsage: rz-bin [-AcdeEghHiIjlLMqrRsSUvVxzZ] [-@ at] [-a arch] [-b bits] [-B addr]\n [-C F:C:D] [-f str] [-m addr] [-n str] [-N m:M] [-P pdb]\n [-o str] [-O str] [-k query] [-D lang symname] file\n -@ [addr] Show section, symbol, or import at the given address\n -A List sub-binaries and their arch-bits pairs\n -a [arch] Set arch (x86, arm, .. or <arch>_<bits>)\n -b [bits] Set bits (32, 64 ...)\n -B [addr] Override base address (pie bins)\n -c List classes\n -cc List classes in header format\n -C [fmt:C:D] Create [elf,mach0,pe] with Code and Data hexpairs (see -a)\n -d Show debug/dwarf information\n -dd Load debug/dwarf information from debuginfod server\n -D lang name Demangle symbol name (-D all for bin.demangle=true)z\n -e Entrypoint\n -ee Constructor/destructor entrypoints\n -E Globally exportable symbols\n -f [str] Select sub-bin named str\n -F [binfmt] Force to use that bin plugin (ignore header check)\n -g Same as -SMZIHVResizcld -SS -SSS -ee (show all info)\n -G [addr] Load address . offset to header\n -h Show this help\n -H Header fields\n -i Import (symbols imported from libraries)\n -I Binary info\n -j Output in JSON\n -k [sdb-query] Run sdb query. for example: '*'\n -K [algo] Calculate checksums (md5, sha1, ..)\n -l Linked libraries\n -L [plugin] List supported bin plugins or plugin details\n -m [addr] Show source line at addr\n -M Main (show address of main symbol)\n -n [str] Show section, symbol or import named str\n -N [min:max] Force min:max number of chars per string (see -z and -zz)\n -o [str] Output file/folder for write operations (out by default)\n -O [str] Write/extract operations (-O help)\n -p Show physical addresses\n -P Show debug/pdb information\n -PP Download pdb file for binary\n -q Quiet mode, just show fewer data\n -qq Show less info (no offset/size for -z for ex.)\n -Q Show load address used by dlopen (non-aslr libs)\n -r Show output in rizin format\n -R Show relocations\n -s Symbols\n -S Sections\n -SS Segments\n -SSS Sections mapping to segments\n -T Display file signature\n -u Unfiltered (no rename duplicated symbols/sections)\n -U Resources\n -v Show version information\n -V Show binary version information\n -w Display try/catch blocks\n -x Extract bins contained in file\n -X [fmt] [f] .. Package in fat or zip the given files and bins contained in file\n -Y [fw file] Calculate all the possibles base address candidates of a firmware bin\n -z Show strings (from data section)\n -zz Show strings (from raw strings from bin)\n -zzz Dump raw strings to stdout (for huge files)\n -Z Guess size of binary program\nEnvironment:\n RZ_BIN_CODESIGN_VERBOSE: # make code signatures verbose\n RZ_BIN_DEBASE64: e bin.debase64 # try to debase64 all strings\n RZ_BIN_DEBUGINFOD_URLS: e bin.dbginfo.debuginfod_urls # use alternative debuginfod server\n RZ_BIN_DEMANGLE=0: e bin.demangle # do not demangle symbols\n RZ_BIN_LANG: e bin.lang # assume lang for demangling\n RZ_BIN_MAXSTRBUF: e str.search.buffer_size # specify maximum buffer size\n RZ_BIN_PDBSERVER: e pdb.server # use alternative PDB server\n RZ_BIN_PREFIX: e bin.prefix # prefix symbols/sections/relocs with a specific string\n RZ_BIN_STRFILTER: e bin.str.filter # rizin -qc 'e bin.str.filter=??' -\n RZ_BIN_STRPURGE: e bin.str.purge # try to purge false positives\n RZ_BIN_SYMSTORE: e pdb.symstore # path to downstream PDB symbol store\n RZ_CONFIG: # config file\n RZ_NOPLUGINS: # do not load plugins", "crumbs": [ "Command Line Tools", - "78  Rz-bin — Show Properties of a Binary" + "79  Rz-bin — Show Properties of a Binary" ] }, { "objectID": "src/tools/rz-bin/file_identification.html", "href": "src/tools/rz-bin/file_identification.html", - "title": "79  File Properties Identification", + "title": "80  File Properties Identification", "section": "", "text": "File type identification is done using -I. With this option, rz-bin prints information on a binary type, like its encoding, endianness, class, operating system:\n$ rz-bin -I /usr/bin/ls\n[Info]\narch x86\ncpu N/A\nbaddr 0x00000000\nbinsz 0x00024280\nbintype elf\nbits 64\nclass ELF64\ncompiler N/A\ndbg_file N/A\nendian LE\nhdr.csum N/A\nguid N/A\nintrp /lib64/ld-linux-x86-64.so.2\nladdr 0x00000000\nlang c\nmachine AMD x86-64 architecture\nmaxopsz 16\nminopsz 1\nos linux\ncc N/A\npcalign 0\nrelro full\nrpath NONE\nsubsys linux\nstripped true\ncrypto false\nhavecode true\nva true\nsanitiz false\nstatic false\nlinenum false\nlsyms false\ncanary true\nPIE true\nRELROCS false\nNX true\nTo make rz-bin output information in format that the main program, Rizin, can understand, pass -Ir option to it:\n$ rz-bin -Ir /bin/ls\ne cfg.bigendian=false\ne asm.bits=64\ne asm.dwarf=true\ne bin.lang=c\ne file.type=elf\ne asm.os=linux\ne asm.arch=x86\ne asm.pcalign=0", "crumbs": [ "Command Line Tools", - "79  File Properties Identification" + "80  File Properties Identification" ] }, { "objectID": "src/tools/rz-bin/entrypoints.html", "href": "src/tools/rz-bin/entrypoints.html", - "title": "80  Code Entrypoints", + "title": "81  Code Entrypoints", "section": "", "text": "The -e option passed to rz-bin will show entrypoints for given binary.\n$ rz-bin -e /usr/bin/ls\n[Entries]\nvaddr paddr hvaddr haddr type \n----------------------------------------------------\n0x00005880 0x00005880 0x00000018 0x00000018 program", "crumbs": [ "Command Line Tools", - "80  Code Entrypoints" + "81  Code Entrypoints" ] }, { "objectID": "src/tools/rz-bin/imports.html", "href": "src/tools/rz-bin/imports.html", - "title": "81  Imports", + "title": "82  Imports", "section": "", "text": "rz-bin is able to find imported objects by an executable, as well as their offsets in its PLT. This information is useful, for example, to understand what external function is invoked by call instruction. Pass -i flag to rz-bin to get a list of imports. An example:\n$ rz-bin -i /usr/bin/ls\n[Imports]\nnth vaddr bind type lib name \n-------------------------------------------------------------\n1 0x000036a0 GLOBAL FUNC __ctype_toupper_loc\n2 0x000036b0 GLOBAL FUNC getenv\n3 0x000036c0 GLOBAL FUNC sigprocmask\n4 0x000036d0 GLOBAL FUNC __snprintf_chk\n5 0x000036e0 GLOBAL FUNC raise\n6 ---------- GLOBAL FUNC __libc_start_main\n7 0x000036f0 GLOBAL FUNC abort\n8 0x00003700 GLOBAL FUNC __errno_location\n9 0x00003710 GLOBAL FUNC strncmp\n10 ---------- WEAK NOTYPE _ITM_deregisterTMCloneTable\n11 0x00003720 GLOBAL FUNC localtime_r\n12 0x00003730 GLOBAL FUNC _exit\n13 0x00003740 GLOBAL FUNC strcpy\n14 0x00003750 GLOBAL FUNC __fpending\n15 0x00003760 GLOBAL FUNC isatty\n16 0x00003770 GLOBAL FUNC sigaction\n17 0x00003780 GLOBAL FUNC iswcntrl\n18 0x00003790 GLOBAL FUNC reallocarray\n19 0x000037a0 GLOBAL FUNC localeconv\n20 0x000037b0 GLOBAL FUNC faccessat\n21 0x000037c0 GLOBAL FUNC readlink\n...", "crumbs": [ "Command Line Tools", - "81  Imports" + "82  Imports" ] }, { "objectID": "src/tools/rz-bin/exports.html", "href": "src/tools/rz-bin/exports.html", - "title": "82  Exports", + "title": "83  Exports", "section": "", "text": "rz-bin is able to find exports. For example:\n$ rz-bin -E /usr/lib64/librz_bin.so | head\nERROR: Cannot determine entrypoint, using 0x00013ea0.\n[Exports]\nnth paddr vaddr bind type size lib name \n-----------------------------------------------------------------------------------------------\n366 0x000f34f0 0x000f34f0 GLOBAL FUNC 94 rz_bin_dwarf_str_from_file\n367 0x0009d020 0x0009d020 GLOBAL FUNC 85 reloc_targets_map_base_64\n368 0x000601b0 0x000601b0 GLOBAL FUNC 153 rz_bin_dex_resolve_class_by_idx\n369 0x0001adc0 0x0001adc0 GLOBAL FUNC 70 rz_bin_reloc_size\n370 0x00018580 0x00018580 GLOBAL FUNC 66 rz_bin_cur\n371 0x000178c0 0x000178c0 GLOBAL FUNC 174 rz_bin_xtr_plugin_del\n372 0x000e42a0 0x000e42a0 GLOBAL FUNC 33 rz_bin_dwarf_addr_free", "crumbs": [ "Command Line Tools", - "82  Exports" + "83  Exports" ] }, { "objectID": "src/tools/rz-bin/symbols.html", "href": "src/tools/rz-bin/symbols.html", - "title": "83  Symbols (Exports)", + "title": "84  Symbols (Exports)", "section": "", "text": "With rz-bin, the generated symbols list format is similar to the imports list. Use the -s option to get it:\n$ rz-bin -s /usr/bin/ls | head\n[Symbols]\nnth paddr vaddr bind type size lib name \n---------------------------------------------------------------------------------\n104 ---------- 0x00025280 GLOBAL OBJ 8 __progname\n105 ---------- 0x00025290 GLOBAL OBJ 4 optind\n107 ---------- 0x000252a8 WEAK OBJ 8 program_invocation_name\n108 ---------- 0x000252a8 GLOBAL OBJ 8 __progname_full\n109 0x00024200 0x00025200 GLOBAL OBJ 8 obstack_alloc_failed_handler\n110 ---------- 0x000252c0 GLOBAL OBJ 8 stderr\n111 ---------- 0x00025280 WEAK OBJ 8 program_invocation_short_name\nWith the -sr option rz-bin produces a rizin script instead. It can later be passed to the core to automatically flag all symbols and to define corresponding byte ranges as functions and data blocks.\n$ rz-bin -sr /usr/bin/ls | head\nfs symbols\nf sym.obstack_allocated_p 56 0x000150a0\nf sym.program_invocation_name 8 0x0021f600\nf sym.stderr 8 0x0021f620\nf sym.obstack_begin_1 21 0x00014f90\nf sym.program_invocation_name 8 0x0021f600\nf sym.obstack_alloc_failed_handler 8 0x0021f5c0\nf sym.optarg 8 0x0021f5f8\nf sym.stdout 8 0x0021f5e8\nf sym.program_invocation_short_name 8 0x0021f5e0", "crumbs": [ "Command Line Tools", - "83  Symbols (Exports)" + "84  Symbols (Exports)" ] }, { "objectID": "src/tools/rz-bin/libraries.html", "href": "src/tools/rz-bin/libraries.html", - "title": "84  List Libraries", + "title": "85  List Libraries", "section": "", "text": "rz-bin can list libraries used by a binary with the -l option:\n$ rz-bin -l `which rizin`\nrz-bin -l `which rizin`\n[Libs]\nlibrary \n------------------\nlibrz_util.so.0.7\nlibrz_main.so.0.7\nlibc.so.6\n\nLet’s check the output with ldd command:\n$ ldd `which rizin`\n linux-vdso.so.1 (0x00007ffe302dd000)\n librz_util.so.0.7 => /usr/lib64/librz_util.so.0.7 (0x00007f6bea740000)\n librz_main.so.0.7 => /usr/lib64/librz_main.so.0.7 (0x00007f6bea705000)\n libc.so.6 => /usr/lib64/libc.so.6 (0x00007f6bea531000)\n libm.so.6 => /usr/lib64/libm.so.6 (0x00007f6bea486000)\n libpcre2-8.so.0 => /usr/lib64/libpcre2-8.so.0 (0x00007f6bea3e8000)\n libz.so.1 => /usr/lib64/libz.so.1 (0x00007f6bea3ce000)\n liblzma.so.5 => /usr/lib64/liblzma.so.5 (0x00007f6bea39e000)\n libcrypto.so.3 => /usr/lib64/libcrypto.so.3 (0x00007f6be9ee7000)\n librz_demangler.so.0.7 => /usr/lib64/librz_demangler.so.0.7 (0x00007f6be9eb7000)\n librz_socket.so.0.7 => /usr/lib64/librz_socket.so.0.7 (0x00007f6be9ea5000)\n librz_flag.so.0.7 => /usr/lib64/librz_flag.so.0.7 (0x00007f6be9e99000)\n librz_cons.so.0.7 => /usr/lib64/librz_cons.so.0.7 (0x00007f6be9e6f000)\n librz_hash.so.0.7 => /usr/lib64/librz_hash.so.0.7 (0x00007f6be9e3c000)\n librz_crypto.so.0.7 => /usr/lib64/librz_crypto.so.0.7 (0x00007f6be9e27000)\n librz_il.so.0.7 => /usr/lib64/librz_il.so.0.7 (0x00007f6be9df9000)\n librz_io.so.0.7 => /usr/lib64/librz_io.so.0.7 (0x00007f6be9dab000)\n librz_reg.so.0.7 => /usr/lib64/librz_reg.so.0.7 (0x00007f6be9d9f000)\n librz_bp.so.0.7 => /usr/lib64/librz_bp.so.0.7 (0x00007f6be9d96000)\n librz_syscall.so.0.7 => /usr/lib64/librz_syscall.so.0.7 (0x00007f6be9d8d000)\n librz_parse.so.0.7 => /usr/lib64/librz_parse.so.0.7 (0x00007f6be9d68000)\n librz_asm.so.0.7 => /usr/lib64/librz_asm.so.0.7 (0x00007f6be9b2b000)\n librz_egg.so.0.7 => /usr/lib64/librz_egg.so.0.7 (0x00007f6be9b18000)\n librz_search.so.0.7 => /usr/lib64/librz_search.so.0.7 (0x00007f6be9b0f000)\n librz_analysis.so.0.7 => /usr/lib64/librz_analysis.so.0.7 (0x00007f6be9876000)\n librz_debug.so.0.7 => /usr/lib64/librz_debug.so.0.7 (0x00007f6be9822000)\n librz_config.so.0.7 => /usr/lib64/librz_config.so.0.7 (0x00007f6be981a000)\n librz_bin.so.0.7 => /usr/lib64/librz_bin.so.0.7 (0x00007f6be96ad000)\n librz_sign.so.0.7 => /usr/lib64/librz_sign.so.0.7 (0x00007f6be969d000)\n librz_core.so.0.7 => /usr/lib64/librz_core.so.0.7 (0x00007f6be93cb000)\n librz_diff.so.0.7 => /usr/lib64/librz_diff.so.0.7 (0x00007f6be93c0000)\n /lib64/ld-linux-x86-64.so.2 (0x00007f6bea860000)\n libssl.so.3 => /usr/lib64/libssl.so.3 (0x00007f6be92d4000)\n libxxhash.so.0 => /usr/lib64/libxxhash.so.0 (0x00007f6be92c8000)\n libzip.so.5 => /usr/lib64/libzip.so.5 (0x00007f6be92ab000)\n libcapstone.so.5 => /usr/lib64/libcapstone.so.5 (0x00007f6be8ba2000)\n librz_type.so.0.7 => /usr/lib64/librz_type.so.0.7 (0x00007f6be8ab0000)\n librz_magic.so.0.7 => /usr/lib64/librz_magic.so.0.7 (0x00007f6be8aab000)\n liblz4.so.1 => /usr/lib64/liblz4.so.1 (0x00007f6be8a84000)\n libzstd.so.1 => /usr/lib64/libzstd.so.1 (0x00007f6be89c9000)\n libmspack.so.0 => /usr/lib64/libmspack.so.0 (0x00007f6be89b4000)\n librz_lang.so.0.7 => /usr/lib64/librz_lang.so.0.7 (0x00007f6be89aa000)\n libbz2.so.1 => /usr/lib64/libbz2.so.1 (0x00007f6be8996000)\n libmagic.so.1 => /usr/lib64/libmagic.so.1 (0x00007f6be896b000)\nIf you compare the outputs of rz-bin -l and ldd, you will notice that rz-bin lists fewer libraries than ldd. The reason is that rz-bin does not follow and does not show dependencies of libraries. Only direct binary dependencies are shown.", "crumbs": [ "Command Line Tools", - "84  List Libraries" + "85  List Libraries" ] }, { "objectID": "src/tools/rz-bin/strings.html", "href": "src/tools/rz-bin/strings.html", - "title": "85  Strings", + "title": "86  Strings", "section": "", "text": "The -z option is used to list readable strings found in the .rodata section of ELF binaries, or the .text section of PE files. Example:\n$ rz-bin -z /usr/bin/ls | head\n[Strings]\nnth paddr vaddr len size section type string \n-------------------------------------------------------\n0 0x00019007 0x00019007 5 6 .rodata ascii =fff?\n1 0x00019630 0x00019630 11 12 .rodata ascii dev_ino_pop\n2 0x000196a8 0x000196a8 10 11 .rodata ascii sort_files\n3 0x000196b3 0x000196b3 6 7 .rodata ascii posix-\n4 0x000196ba 0x000196ba 4 5 .rodata ascii main\n5 0x00019790 0x00019790 10 11 .rodata ascii ?pcdb-lswd\n6 0x000197a0 0x000197a0 65 66 .rodata ascii # Configuration file for dircolors, a utility to help you set the\nWith the -zr option, this information is represented as a rizin commands list. It can be used in a rizin session to automatically create a flag space called “strings” pre-populated with flags for all strings found by rz-bin. Furthermore, this script will mark corresponding byte ranges as strings instead of code.\n\n$ rz-bin -zr /usr/bin/ls | head\nfs stringsf str.dev_ino_pop 12 @ 0x000160f8\nCs 12 @ 0x000160f8\nf str.sort_files 11 @ 0x00016188\nCs 11 @ 0x00016188\nf str.posix 7 @ 0x00016193\nCs 7 @ 0x00016193\nf str.main 5 @ 0x0001619a\nCs 5 @ 0x0001619a\nf str.pcdb_lswd 11 @ 0x00016250\nCs 11 @ 0x00016250", "crumbs": [ "Command Line Tools", - "85  Strings" + "86  Strings" ] }, { "objectID": "src/tools/rz-bin/program_sections.html", "href": "src/tools/rz-bin/program_sections.html", - "title": "86  Program Sections", + "title": "87  Program Sections", "section": "", "text": "rz-bin called with the -S option gives complete information about the sections of an executable. For each section the index, offset, size, alignment, type and permissions, are shown. The next example demonstrates this:\n$ rz-bin -S /usr/bin/ls\n[Sections]\npaddr size vaddr vsize align perm name type flags \n---------------------------------------------------------------------------------------------\n0x00000000 0x0 ---------- 0x0 0x0 ---- NULL \n0x00000318 0x1c 0x00000318 0x1c 0x0 -r-- .interp PROGBITS alloc\n0x00000338 0x50 0x00000338 0x50 0x0 -r-- .note.gnu.property NOTE alloc\n0x00000388 0x20 0x00000388 0x20 0x0 -r-- .note.ABI-tag NOTE alloc\n0x000003a8 0x98 0x000003a8 0x98 0x0 -r-- .gnu.hash GNU_HASH alloc\n0x00000440 0xaf8 0x00000440 0xaf8 0x0 -r-- .dynsym DYNSYM alloc\n0x00000f38 0x564 0x00000f38 0x564 0x0 -r-- .dynstr STRTAB alloc\n0x0000149c 0xea 0x0000149c 0xea 0x0 -r-- .gnu.version VERSYM alloc\n0x00001588 0xe0 0x00001588 0xe0 0x0 -r-- .gnu.version_r VERNEED alloc\n0x00001668 0x150 0x00001668 0x150 0x0 -r-- .rela.dyn RELA alloc\n0x000017b8 0x948 0x000017b8 0x948 0x0 -r-- .rela.plt RELA alloc,info\n0x00002100 0x50 0x00002100 0x50 0x0 -r-- .relr.dyn NUM alloc\n0x00003000 0x1b 0x00003000 0x1b 0x0 -r-x .init PROGBITS alloc,execute\n0x00003020 0x640 0x00003020 0x640 0x0 -r-x .plt PROGBITS alloc,execute\n0x00003660 0x40 0x00003660 0x40 0x0 -r-x .plt.got PROGBITS alloc,execute\n0x000036a0 0x630 0x000036a0 0x630 0x0 -r-x .plt.sec PROGBITS alloc,execute\n0x00003cd0 0x14972 0x00003cd0 0x14972 0x0 -r-x .text PROGBITS alloc,execute\n0x00018644 0xd 0x00018644 0xd 0x0 -r-x .fini PROGBITS alloc,execute\n0x00019000 0x5453 0x00019000 0x5453 0x0 -r-- .rodata PROGBITS alloc\n0x0001e454 0x9b4 0x0001e454 0x9b4 0x0 -r-- .eh_frame_hdr PROGBITS alloc\n0x0001ee08 0x3348 0x0001ee08 0x3348 0x0 -r-- .eh_frame PROGBITS alloc\n0x00022f50 0x8 0x00023f50 0x8 0x0 -rw- .init_array INIT_ARRAY write,alloc\n0x00022f58 0x8 0x00023f58 0x8 0x0 -rw- .fini_array FINI_ARRAY write,alloc\n0x00022f60 0xaf8 0x00023f60 0xaf8 0x0 -rw- .data.rel.ro PROGBITS write,alloc\n0x00023a58 0x220 0x00024a58 0x220 0x0 -rw- .dynamic DYNAMIC write,alloc\n0x00023c78 0x370 0x00024c78 0x370 0x0 -rw- .got PROGBITS write,alloc\n0x00024000 0x280 0x00025000 0x280 0x0 -rw- .data PROGBITS write,alloc\n0x00024280 0x0 0x00025280 0x12d8 0x0 -rw- .bss NOBITS write,alloc\n0x00024280 0x105 ---------- 0x105 0x0 ---- .shstrtab STRTAB \nWith the -Sr option, rz-bin will flag the start/end of every section, and will pass the rest of information as a comment.\n$ rz-bin -Sr /usr/bin/ls | head\nfs sections\n\"f section. 1 0x00000000\"\n\"f section..interp 1 0x000002a8\"\n\"f section..note.gnu.build_id 1 0x000002c4\"\n\"f section..note.ABI_tag 1 0x000002e8\"\n\"f section..gnu.hash 1 0x00000308\"\n\"f section..dynsym 1 0x000003b8\"\n\"f section..dynstr 1 0x00000fb8\"\n\"f section..gnu.version 1 0x00001574\"\n\"f section..gnu.version_r 1 0x00001678\"", "crumbs": [ "Command Line Tools", - "86  Program Sections" + "87  Program Sections" ] }, { "objectID": "src/tools/rz-diff/intro.html", "href": "src/tools/rz-diff/intro.html", - "title": "87  Rz-diff", + "title": "88  Rz-diff", "section": "", "text": "rz-diff is a tool designed to compare binary files, similar to how regular diff compares text files.\n$ rz-diff -h\nUsage: rz-diff [options] <file0> <file1>\n -a [arch] Specify architecture plugin to use (x86, arm, ..)\n -b [bits] Specify register size for arch (16 (thumb), 32, 64, ..)\n -d [algo] Compute edit distance based on the chosen algorithm:\n myers | Eugene W. Myers' O(ND) algorithm (no substitution)\n leven | Levenshtein O(N^2) algorithm (with substitution)\n ssdeep | Context triggered piecewise hashing comparison\n -i Use command line arguments instead of files (only for -d)\n -H Hexadecimal visual mode\n -h Show this help\n -j JSON output\n -q Quite output\n -V Show version information\n -v Be more verbose (stderr output)\n -e [k=v] Set an evaluable config variable\n -A Compare virtual and physical addresses\n -B Run 'aaa' when loading the bin\n -C Disable colors\n -T Show timestamp information\n -S [WxH] Set the width and height of the terminal for visual mode\n -0 [cmd] Input for file0 when option -t 'commands' is given.\n The same value will be set for file1, if -1 is not set.\n -1 [cmd] Input for file1 when option -t 'commands' is given.\n -t [type] Compute the difference between two files based on its type:\n bytes | compare raw bytes in the files (only for small files)\n lines | compare text files\n functions | compare functions found in the files\n classes | compare classes found in the files\n command | compare command output returned when executed in both files\n | require -0 <cmd> and -1 <cmd> is optional\n entries | compare entries found in the files\n fields | compare fields found in the files\n graphs | compare 2 functions and outputs in graphviz/dot format\n | require -0 <fcn name|offset> and -1 <fcn name|offset> is optional\n imports | compare imports found in the files\n libraries | compare libraries found in the files\n sections | compare sections found in the files\n strings | compare strings found in the files\n symbols | compare symbols found in the files\npalette colors can be changed by adding the following lines\ninside the $HOME/.rizinrc file\nec diff.unknown blue | offset color\nec diff.match green | match color\nec diff.unmatch red | mismatch color", "crumbs": [ "Command Line Tools", - "87  Rz-diff" + "88  Rz-diff" ] }, { "objectID": "src/tools/rz-diff/binary_diffing.html", "href": "src/tools/rz-diff/binary_diffing.html", - "title": "88  Rz-Diff (binary and text diffing utility)", + "title": "89  Rz-Diff (binary and text diffing utility)", "section": "", - "text": "88.1 Distance\nFor bulk processing, you may want to have a higher-level overview of differences.\nThe -d option serves to calculate the distance between the two binaries using either Myers algorithm or the Levenshtein algorithm.", + "text": "89.1 Distance\nFor bulk processing, you may want to have a higher-level overview of differences.\nThe -d option serves to calculate the distance between the two binaries using either Myers algorithm or the Levenshtein algorithm.", "crumbs": [ "Command Line Tools", - "88  Rz-Diff (binary and text diffing utility)" + "89  Rz-Diff (binary and text diffing utility)" ] }, { "objectID": "src/tools/rz-diff/binary_diffing.html#distance", "href": "src/tools/rz-diff/binary_diffing.html#distance", - "title": "88  Rz-Diff (binary and text diffing utility)", + "title": "89  Rz-Diff (binary and text diffing utility)", "section": "", - "text": "-d --------> myers (myers algorithm)\n |----> leven (levenshtein algorithm)\n\n88.1.1 Myers algorithm:\nIn the Myers algorithm for edit distance, the cost of an insertion or deletion is 1 and the cost of a replacement is 2. The theorem leads directly to an O(k) algorithm for incrementally computing a new solution from an old one, as contrasts the O(k2) time required to compute a solution from scratch. Thus, the algorithm performs well when the two strings are similar.\n$ rz-diff -d myers /usr/bin/true /usr/bin/false\nsimilarity: 0.997\ndistance: 242\n\n\n88.1.2 Levenshtein distance:\nLevenshtein distance is a string metric for measuring the difference between two sequences. Informally, the Levenshtein distance between two words is the minimum number of single-character edits (insertions, deletions or substitutions) required to change one word into the other.\n$ rz-diff -d leven /bin/true /bin/false\nsimilarity: 0.997\ndistance: 130", + "text": "-d --------> myers (myers algorithm)\n |----> leven (levenshtein algorithm)\n\n89.1.1 Myers algorithm:\nIn the Myers algorithm for edit distance, the cost of an insertion or deletion is 1 and the cost of a replacement is 2. The theorem leads directly to an O(k) algorithm for incrementally computing a new solution from an old one, as contrasts the O(k2) time required to compute a solution from scratch. Thus, the algorithm performs well when the two strings are similar.\n$ rz-diff -d myers /usr/bin/true /usr/bin/false\nsimilarity: 0.997\ndistance: 242\n\n\n89.1.2 Levenshtein distance:\nLevenshtein distance is a string metric for measuring the difference between two sequences. Informally, the Levenshtein distance between two words is the minimum number of single-character edits (insertions, deletions or substitutions) required to change one word into the other.\n$ rz-diff -d leven /bin/true /bin/false\nsimilarity: 0.997\ndistance: 130", "crumbs": [ "Command Line Tools", - "88  Rz-Diff (binary and text diffing utility)" + "89  Rz-Diff (binary and text diffing utility)" ] }, { "objectID": "src/tools/rz-diff/binary_diffing.html#hexadecimal-diffing", "href": "src/tools/rz-diff/binary_diffing.html#hexadecimal-diffing", - "title": "88  Rz-Diff (binary and text diffing utility)", - "section": "88.2 Hexadecimal Diffing:", - "text": "88.2 Hexadecimal Diffing:\n-H The hexadecimal displays the hexdump of file0 vs file1 in a side-by-side window. Navigational keys allows easily parsing through the hexdump of the files individually.\n\n1 and 2 : to move to the next or previous page.\nZ and A : allows parsing forward and backward through file0, byte by byte.\nC and D : allows parsing forward and backward through file1, byte by byte.\nG and B : seeks the end and beginning of the files.\nN and M : takes you to the Next and the Previous differing byte in the files respectively.\n/\\ and \\/ : parsing both binaries simultaneously, 16 bytes a time.\n< and > : parsing both binaries simultaneously, by 1 byte.\n: <seek address in hex/decimal> : seeks the address provided and bring the window to start dump from the seeked address.\n? : shows the help screen in the visual mode which can be exited with ‘q’/esc keys.\n\nThe bytes that differ are: rz-diff -H /bin/true /bin/false\n$ rz-bin -s /usr/bin/ls | head\n[Symbols]\nnth paddr vaddr bind type size lib name \n---------------------------------------------------------------------------------\n104 ---------- 0x00025280 GLOBAL OBJ 8 __progname\n105 ---------- 0x00025290 GLOBAL OBJ 4 optind\n107 ---------- 0x000252a8 WEAK OBJ 8 program_invocation_name\n┌─────────────────────────── [a8c8]( true )─────────────────────────────────────────────────────────────────────────── [a8c8]( false )─────────────────────────────────────────────────────────────────────────────────────────────────────┐\n│ 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F │\n│ 0x0000000000000000 | 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 | .ELF............ | 0x0000000000000000 | 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 | .ELF............ | │\n│ 0x0000000000000010 | 03 00 3e 00 01 00 00 00 80 26 00 00 00 00 00 00 | ..>......&...... | 0x0000000000000010 | 03 00 3e 00 01 00 00 00 80 26 00 00 00 00 00 00 | ..>......&...... | │\n│ 0x0000000000000020 | 40 00 00 00 00 00 00 00 88 a1 00 00 00 00 00 00 | @............... | 0x0000000000000020 | 40 00 00 00 00 00 00 00 88 a1 00 00 00 00 00 00 | @............... | │\n│ 0x0000000000000030 | 00 00 00 00 40 00 38 00 0d 00 40 00 1d 00 1c 00 | ....@.8...@..... | 0x0000000000000030 | 00 00 00 00 40 00 38 00 0d 00 40 00 1d 00 1c 00 | ....@.8...@..... | │\n│ 0x0000000000000040 | 06 00 00 00 04 00 00 00 40 00 00 00 00 00 00 00 | ........@....... | 0x0000000000000040 | 06 00 00 00 04 00 00 00 40 00 00 00 00 00 00 00 | ........@....... | │\n│ 0x0000000000000050 | 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 | @.......@....... | 0x0000000000000050 | 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 | @.......@....... | │\n│ 0x0000000000000060 | d8 02 00 00 00 00 00 00 d8 02 00 00 00 00 00 00 | ................ | 0x0000000000000060 | d8 02 00 00 00 00 00 00 d8 02 00 00 00 00 00 00 | ................ | │\n│ 0x0000000000000070 | 08 00 00 00 00 00 00 00 03 00 00 00 04 00 00 00 | ................ | 0x0000000000000070 | 08 00 00 00 00 00 00 00 03 00 00 00 04 00 00 00 | ................ | │\n│ 0x0000000000000080 | 18 03 00 00 00 00 00 00 18 03 00 00 00 00 00 00 | ................ | 0x0000000000000080 | 18 03 00 00 00 00 00 00 18 03 00 00 00 00 00 00 | ................ | │\n│ 0x0000000000000090 | 18 03 00 00 00 00 00 00 1c 00 00 00 00 00 00 00 | ................ | 0x0000000000000090 | 18 03 00 00 00 00 00 00 1c 00 00 00 00 00 00 00 | ................ | │\n\n...\n\n│ 0x0000000000000360 | 07 00 00 00 00 00 00 00 01 00 01 c0 04 00 00 00 | ................ | 0x0000000000000360 | 07 00 00 00 00 00 00 00 01 00 01 c0 04 00 00 00 | ................ | │\n│ 0x0000000000000370 | 19 00 00 00 00 00 00 00 02 00 01 c0 04 00 00 00 | ................ | 0x0000000000000370 | 19 00 00 00 00 00 00 00 02 00 01 c0 04 00 00 00 | ................ | │\n└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘\n 1 2 -/+0x390 | Z A file0 +/-1 | C D file1 +/-1 | G B end/begin | N M next/prev | ᐯ ᐱ +/-16 | ᐸ ᐳ +/-1 | : seek\n-S mode allows you to adjust the window size of the hexadecimal view to your preference. Minimmum: W = 120 H = 20\nExample : rz-diff -HS 120x20 /bin/true /bin/false\n\n88.2.1 File Type Based Diffing\nt option computes the difference between two files based on its type.\n -t [type] Compute the difference between two files based on its type:\n bytes | compare raw bytes in the files (only for small files)\n lines | compare text files\n functions | compare functions found in the files\n classes | compare classes found in the files\n command | compare command output returned when executed in both files\n | require -0 <cmd> and -1 <cmd> is optional\n entries | compare entries found in the files\n fields | compare fields found in the files\n graphs | compare 2 functions and outputs in graphviz/dot format\n | require -0 <fcn name|offset> and -1 <fcn name|offset> is optional\n imports | compare imports found in the files\n libraries | compare libraries found in the files\n sections | compare sections found in the files\n strings | compare strings found in the files\n symbols | compare symbols found in the files\n\n\n88.2.2 Diffing ASCII-text files:\n$ rz-diff -t lines genuine cracked\n--- genuine\n+++ cracked\n@@ -1,1 +1,1 @@\n-hello1234567890\n+1234567890hello\n\n\n88.2.3 Diffing functions in binaries:\nIt this mode, it will give you three columns for all functions: “First file offset”, “Percentage of matching” and “Second file offset”.\nrz-diff -t functions /usr/bin/true /usr/bin/false\n.-----------------------------------------------------------------------------------------------------------------------------------.\n| name0 | size0 | addr0 | type | similarity | addr1 | size1 | name1 |\n)-----------------------------------------------------------------------------------------------------------------------------------(\n| fcn.000022c0 | 10 | 0x000022c0 | COMPLETE | 1.000000 | 0x000022c0 | 10 | fcn.000022c0 |\n| sym.imp.free | 10 | 0x000022d0 | COMPLETE | 1.000000 | 0x000022d0 | 10 | sym.imp.free |\n| sym.imp.abort | 10 | 0x000022e0 | COMPLETE | 1.000000 | 0x000022e0 | 10 | sym.imp.abort |\n| sym.imp.__errno_location | 10 | 0x000022f0 | COMPLETE | 1.000000 | 0x000022f0 | 10 | sym.imp.__errno_location |\n| sym.imp.strncmp | 10 | 0x00002300 | COMPLETE | 1.000000 | 0x00002300 | 10 | sym.imp.strncmp |\n| sym.imp._exit | 10 | 0x00002310 | COMPLETE | 1.000000 | 0x00002310 | 10 | sym.imp._exit |\n| sym.imp.__fpending | 10 | 0x00002320 | COMPLETE | 1.000000 | 0x00002320 | 10 | sym.imp.__fpending |\n| sym.imp.reallocarray | 10 | 0x00002330 | COMPLETE | 1.000000 | 0x00002330 | 10 | sym.imp.reallocarray |\n| sym.imp.textdomain | 10 | 0x00002340 | COMPLETE | 1.000000 | 0x00002340 | 10 | sym.imp.textdomain |\n| sym.imp.fclose | 10 | 0x00002350 | COMPLETE | 1.000000 | 0x00002350 | 10 | sym.imp.fclose |\n| sym.imp.bindtextdomain | 10 | 0x00002360 | COMPLETE | 1.000000 | 0x00002360 | 10 | sym.imp.bindtextdomain |\n| sym.imp.dcgettext | 10 | 0x00002370 | COMPLETE | 1.000000 | 0x00002370 | 10 | sym.imp.dcgettext |\n| sym.imp.__ctype_get_mb_cur_max | 10 | 0x00002380 | COMPLETE | 1.000000 | 0x00002380 | 10 | sym.imp.__ctype_get_mb_cur_max |\n| sym.imp.strlen | 10 | 0x00002390 | COMPLETE | 1.000000 | 0x00002390 | 10 | sym.imp.strlen |\n| sym.imp.__stack_chk_fail | 10 | 0x000023a0 | COMPLETE | 1.000000 | 0x000023a0 | 10 | sym.imp.__stack_chk_fail |\n| sym.imp.strrchr | 10 | 0x000023b0 | COMPLETE | 1.000000 | 0x000023b0 | 10 | sym.imp.strrchr |\n| sym.imp.lseek | 10 | 0x000023c0 | COMPLETE | 1.000000 | 0x000023c0 | 10 | sym.imp.lseek |\n| sym.imp.memset | 10 | 0x000023d0 | COMPLETE | 1.000000 | 0x000023d0 | 10 | sym.imp.memset |\n| sym.imp.mbrtoc32 | 10 | 0x000023e0 | COMPLETE | 1.000000 | 0x000023e0 | 10 | sym.imp.mbrtoc32 |\n| sym.imp.memcmp | 10 | 0x000023f0 | COMPLETE | 1.000000 | 0x000023f0 | 10 | sym.imp.memcmp |\n| sym.imp.fputs_unlocked | 10 | 0x00002400 | COMPLETE | 1.000000 | 0x00002400 | 10 | sym.imp.fputs_unlocked |\n| sym.imp.calloc | 10 | 0x00002410 | COMPLETE | 1.000000 | 0x00002410 | 10 | sym.imp.calloc |\n| sym.imp.strcmp | 10 | 0x00002420 | COMPLETE | 1.000000 | 0x00002420 | 10 | sym.imp.strcmp |\n| sym.imp.fputc_unlocked | 10 | 0x00002430 | COMPLETE | 1.000000 | 0x00002430 | 10 | sym.imp.fputc_unlocked |\n| sym.imp.memcpy | 10 | 0x00002440 | COMPLETE | 1.000000 | 0x00002440 | 10 | sym.imp.memcpy |\n| sym.imp.fileno | 10 | 0x00002450 | COMPLETE | 1.000000 | 0x00002450 | 10 | sym.imp.fileno |\n| sym.imp.malloc | 10 | 0x00002460 | COMPLETE | 1.000000 | 0x00002460 | 10 | sym.imp.malloc |\n| sym.imp.nl_langinfo | 10 | 0x00002480 | COMPLETE | 1.000000 | 0x00002480 | 10 | sym.imp.nl_langinfo |\n| sym.imp.__freading | 10 | 0x00002490 | COMPLETE | 1.000000 | 0x00002490 | 10 | sym.imp.__freading |\n| sym.imp.realloc | 10 | 0x000024a0 | COMPLETE | 1.000000 | 0x000024a0 | 10 | sym.imp.realloc |\n| sym.imp.setlocale | 10 | 0x000024b0 | COMPLETE | 1.000000 | 0x000024b0 | 10 | sym.imp.setlocale |\n| sym.imp.__printf_chk | 10 | 0x000024c0 | COMPLETE | 1.000000 | 0x000024c0 | 10 | sym.imp.__printf_chk |\n| sym.imp.error | 10 | 0x000024d0 | COMPLETE | 1.000000 | 0x000024d0 | 10 | sym.imp.error |\n| sym.imp.exit | 10 | 0x00002500 | COMPLETE | 1.000000 | 0x00002500 | 10 | sym.imp.exit |\n| sym.imp.fwrite | 10 | 0x00002510 | COMPLETE | 1.000000 | 0x00002510 | 10 | sym.imp.fwrite |\n| sym.imp.__fprintf_chk | 10 | 0x00002520 | COMPLETE | 1.000000 | 0x00002520 | 10 | sym.imp.__fprintf_chk |\n| sym.imp.mbsinit | 10 | 0x00002530 | COMPLETE | 1.000000 | 0x00002530 | 10 | sym.imp.mbsinit |\n| sym.imp.iswprint | 10 | 0x00002540 | COMPLETE | 1.000000 | 0x00002540 | 10 | sym.imp.iswprint |\n| sym.imp.__ctype_b_loc | 10 | 0x00002550 | COMPLETE | 1.000000 | 0x00002550 | 10 | sym.imp.__ctype_b_loc |\n| fcn.000026b0 | 34 | 0x000026b0 | COMPLETE | 1.000000 | 0x000026b0 | 34 | fcn.000026b0 |\n| fcn.00002770 | 833 | 0x00002770 | PARTIAL | 0.979592 | 0x00002770 | 833 | fcn.00002770 |\n| fcn.00002ba0 | 166 | 0x00002ba0 | PARTIAL | 0.993976 | 0x00002ba0 | 166 | fcn.00002ba0 |\n| fcn.00002c50 | 79 | 0x00002c50 | PARTIAL | 0.987342 | 0x00002c50 | 79 | fcn.00002c50 |\n| fcn.00002cb0 | 220 | 0x00002cb0 | PARTIAL | 0.972727 | 0x00002cb0 | 220 | fcn.00002cb0 |\n| fcn.00002da0 | 5447 | 0x00002da0 | PARTIAL | 0.998348 | 0x00002da0 | 5447 | fcn.00002da0 |\n| fcn.00004370 | 486 | 0x00004370 | COMPLETE | 1.000000 | 0x00004370 | 486 | fcn.00004370 |\n| fcn.00004c20 | 120 | 0x00004c20 | COMPLETE | 1.000000 | 0x00004c20 | 120 | fcn.00004c20 |\n| fcn.00005070 | 1092 | 0x00005070 | PARTIAL | 0.991758 | 0x00005070 | 1092 | fcn.00005070 |\n| fcn.000055c0 | 210 | 0x000055c0 | COMPLETE | 1.000000 | 0x000055c0 | 210 | fcn.000055c0 |\n| fcn.000057f0 | 28 | 0x000057f0 | COMPLETE | 1.000000 | 0x000057f0 | 28 | fcn.000057f0 |\n| fcn.00005a80 | 241 | 0x00005a80 | COMPLETE | 1.000000 | 0x00005a80 | 241 | fcn.00005a80 |\n| fcn.00005c20 | 54 | 0x00005c20 | COMPLETE | 1.000000 | 0x00005c20 | 54 | fcn.00005c20 |\n| fcn.00005d20 | 56 | 0x00005d20 | PARTIAL | 0.964286 | 0x00005d20 | 56 | fcn.00005d20 |\n| fcn.00005d60 | 93 | 0x00005d60 | COMPLETE | 1.000000 | 0x00005d60 | 93 | fcn.00005d60 |\n| fcn.00005dc0 | 88 | 0x00005dc0 | COMPLETE | 1.000000 | 0x00005dc0 | 88 | fcn.00005dc0 |\n| fcn.00005e20 | 124 | 0x00005e20 | COMPLETE | 1.000000 | 0x00005e20 | 124 | fcn.00005e20 |\n| fcn.00005eb0 | 63 | 0x00005eb0 | COMPLETE | 1.000000 | 0x00005eb0 | 63 | fcn.00005eb0 |\n| fcn.00005ef0 | 109 | 0x00005ef0 | COMPLETE | 1.000000 | 0x00005ef0 | 109 | fcn.00005ef0 |\n| fcn.00005f70 | 54 | 0x00005f70 | PARTIAL | 0.962963 | 0x00005f70 | 54 | fcn.00005f70 |\n| fcn.00005fb0 | 180 | 0x00005fb0 | PARTIAL | 0.994444 | 0x00005fb0 | 180 | fcn.00005fb0 |\n| fcn.00006070 | 116 | 0x00006070 | COMPLETE | 1.000000 | 0x00006070 | 116 | fcn.00006070 |\n| fcn.000060f0 | 128 | 0x000060f0 | COMPLETE | 1.000000 | 0x000060f0 | 128 | fcn.000060f0 |\n| fcn.000061b0 | 18 | 0x000061b0 | COMPLETE | 1.000000 | 0x000061b0 | 18 | fcn.000061b0 |\n`-----------------------------------------------------------------------------------------------------------------------------------'\n\n\n88.2.4 Diffing classes in binaries:\nrz-diff -t classes /usr/bin/true /usr/bin/false\n--- /usr/bin/true\n+++ /usr/bin/false\n\n\n88.2.5 Commands\n\n\n88.2.6 Diffing entries in binaries\nrz-diff -t entries /usr/bin/true /usr/bin/false\n--- /usr/bin/true\n+++ /usr/bin/false\n\n\n88.2.7 Diffing fields in binaries:\nrz-diff -t fields /usr/bin/true /usr/bin/false\n--- /usr/bin/true\n+++ /usr/bin/false\n\n\n88.2.8 Diffing sections in binaries:\nrz-diff -t sections /usr/bin/true /usr/bin/false\n--- /usr/bin/true\n+++ /usr/bin/false\n\n\n88.2.9 Diffing strings in binaries:\nrz-diff -t strings /usr/bin/true /usr/bin/false\n--- /usr/bin/true\n+++ /usr/bin/false\n@@ -10,7 +10,7 @@\n --help display this help and exit\n\n Written by %s, %s, %s,\n%s, %s, %s, %s,\nand %s.\n\n Copyright %s %d Free Software Foundation, Inc.\n-Exit with a status code indicating success.\n+Exit with a status code indicating failure.\n Written by %s, %s, %s,\n%s, %s, %s, and %s.\n\n Written by %s, %s, %s,\n%s, %s, and %s.\n\n https://www.gnu.org/software/coreutils/\n@@ -59,6 +59,6 @@\n ASCII\n POSIX\n UTF-8\n+false\n shell\n %s\n\n\n-true\n\n\n\n88.2.10 Diffing symbols in binaries:\nrz-diff -t symbols /usr/bin/true /usr/bin/false\n--- /usr/bin/true\n+++ /usr/bin/false", + "title": "89  Rz-Diff (binary and text diffing utility)", + "section": "89.2 Hexadecimal Diffing:", + "text": "89.2 Hexadecimal Diffing:\n-H The hexadecimal displays the hexdump of file0 vs file1 in a side-by-side window. Navigational keys allows easily parsing through the hexdump of the files individually.\n\n1 and 2 : to move to the next or previous page.\nZ and A : allows parsing forward and backward through file0, byte by byte.\nC and D : allows parsing forward and backward through file1, byte by byte.\nG and B : seeks the end and beginning of the files.\nN and M : takes you to the Next and the Previous differing byte in the files respectively.\n/\\ and \\/ : parsing both binaries simultaneously, 16 bytes a time.\n< and > : parsing both binaries simultaneously, by 1 byte.\n: <seek address in hex/decimal> : seeks the address provided and bring the window to start dump from the seeked address.\n? : shows the help screen in the visual mode which can be exited with ‘q’/esc keys.\n\nThe bytes that differ are: rz-diff -H /bin/true /bin/false\n$ rz-bin -s /usr/bin/ls | head\n[Symbols]\nnth paddr vaddr bind type size lib name \n---------------------------------------------------------------------------------\n104 ---------- 0x00025280 GLOBAL OBJ 8 __progname\n105 ---------- 0x00025290 GLOBAL OBJ 4 optind\n107 ---------- 0x000252a8 WEAK OBJ 8 program_invocation_name\n┌─────────────────────────── [a8c8]( true )─────────────────────────────────────────────────────────────────────────── [a8c8]( false )─────────────────────────────────────────────────────────────────────────────────────────────────────┐\n│ 0 1 2 3 4 5 6 7 8 9 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F │\n│ 0x0000000000000000 | 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 | .ELF............ | 0x0000000000000000 | 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 | .ELF............ | │\n│ 0x0000000000000010 | 03 00 3e 00 01 00 00 00 80 26 00 00 00 00 00 00 | ..>......&...... | 0x0000000000000010 | 03 00 3e 00 01 00 00 00 80 26 00 00 00 00 00 00 | ..>......&...... | │\n│ 0x0000000000000020 | 40 00 00 00 00 00 00 00 88 a1 00 00 00 00 00 00 | @............... | 0x0000000000000020 | 40 00 00 00 00 00 00 00 88 a1 00 00 00 00 00 00 | @............... | │\n│ 0x0000000000000030 | 00 00 00 00 40 00 38 00 0d 00 40 00 1d 00 1c 00 | ....@.8...@..... | 0x0000000000000030 | 00 00 00 00 40 00 38 00 0d 00 40 00 1d 00 1c 00 | ....@.8...@..... | │\n│ 0x0000000000000040 | 06 00 00 00 04 00 00 00 40 00 00 00 00 00 00 00 | ........@....... | 0x0000000000000040 | 06 00 00 00 04 00 00 00 40 00 00 00 00 00 00 00 | ........@....... | │\n│ 0x0000000000000050 | 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 | @.......@....... | 0x0000000000000050 | 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 | @.......@....... | │\n│ 0x0000000000000060 | d8 02 00 00 00 00 00 00 d8 02 00 00 00 00 00 00 | ................ | 0x0000000000000060 | d8 02 00 00 00 00 00 00 d8 02 00 00 00 00 00 00 | ................ | │\n│ 0x0000000000000070 | 08 00 00 00 00 00 00 00 03 00 00 00 04 00 00 00 | ................ | 0x0000000000000070 | 08 00 00 00 00 00 00 00 03 00 00 00 04 00 00 00 | ................ | │\n│ 0x0000000000000080 | 18 03 00 00 00 00 00 00 18 03 00 00 00 00 00 00 | ................ | 0x0000000000000080 | 18 03 00 00 00 00 00 00 18 03 00 00 00 00 00 00 | ................ | │\n│ 0x0000000000000090 | 18 03 00 00 00 00 00 00 1c 00 00 00 00 00 00 00 | ................ | 0x0000000000000090 | 18 03 00 00 00 00 00 00 1c 00 00 00 00 00 00 00 | ................ | │\n\n...\n\n│ 0x0000000000000360 | 07 00 00 00 00 00 00 00 01 00 01 c0 04 00 00 00 | ................ | 0x0000000000000360 | 07 00 00 00 00 00 00 00 01 00 01 c0 04 00 00 00 | ................ | │\n│ 0x0000000000000370 | 19 00 00 00 00 00 00 00 02 00 01 c0 04 00 00 00 | ................ | 0x0000000000000370 | 19 00 00 00 00 00 00 00 02 00 01 c0 04 00 00 00 | ................ | │\n└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘\n 1 2 -/+0x390 | Z A file0 +/-1 | C D file1 +/-1 | G B end/begin | N M next/prev | ᐯ ᐱ +/-16 | ᐸ ᐳ +/-1 | : seek\n-S mode allows you to adjust the window size of the hexadecimal view to your preference. Minimmum: W = 120 H = 20\nExample : rz-diff -HS 120x20 /bin/true /bin/false\n\n89.2.1 File Type Based Diffing\nt option computes the difference between two files based on its type.\n -t [type] Compute the difference between two files based on its type:\n bytes | compare raw bytes in the files (only for small files)\n lines | compare text files\n functions | compare functions found in the files\n classes | compare classes found in the files\n command | compare command output returned when executed in both files\n | require -0 <cmd> and -1 <cmd> is optional\n entries | compare entries found in the files\n fields | compare fields found in the files\n graphs | compare 2 functions and outputs in graphviz/dot format\n | require -0 <fcn name|offset> and -1 <fcn name|offset> is optional\n imports | compare imports found in the files\n libraries | compare libraries found in the files\n sections | compare sections found in the files\n strings | compare strings found in the files\n symbols | compare symbols found in the files\n\n\n89.2.2 Diffing ASCII-text files:\n$ rz-diff -t lines genuine cracked\n--- genuine\n+++ cracked\n@@ -1,1 +1,1 @@\n-hello1234567890\n+1234567890hello\n\n\n89.2.3 Diffing functions in binaries:\nIt this mode, it will give you three columns for all functions: “First file offset”, “Percentage of matching” and “Second file offset”.\nrz-diff -t functions /usr/bin/true /usr/bin/false\n.-----------------------------------------------------------------------------------------------------------------------------------.\n| name0 | size0 | addr0 | type | similarity | addr1 | size1 | name1 |\n)-----------------------------------------------------------------------------------------------------------------------------------(\n| fcn.000022c0 | 10 | 0x000022c0 | COMPLETE | 1.000000 | 0x000022c0 | 10 | fcn.000022c0 |\n| sym.imp.free | 10 | 0x000022d0 | COMPLETE | 1.000000 | 0x000022d0 | 10 | sym.imp.free |\n| sym.imp.abort | 10 | 0x000022e0 | COMPLETE | 1.000000 | 0x000022e0 | 10 | sym.imp.abort |\n| sym.imp.__errno_location | 10 | 0x000022f0 | COMPLETE | 1.000000 | 0x000022f0 | 10 | sym.imp.__errno_location |\n| sym.imp.strncmp | 10 | 0x00002300 | COMPLETE | 1.000000 | 0x00002300 | 10 | sym.imp.strncmp |\n| sym.imp._exit | 10 | 0x00002310 | COMPLETE | 1.000000 | 0x00002310 | 10 | sym.imp._exit |\n| sym.imp.__fpending | 10 | 0x00002320 | COMPLETE | 1.000000 | 0x00002320 | 10 | sym.imp.__fpending |\n| sym.imp.reallocarray | 10 | 0x00002330 | COMPLETE | 1.000000 | 0x00002330 | 10 | sym.imp.reallocarray |\n| sym.imp.textdomain | 10 | 0x00002340 | COMPLETE | 1.000000 | 0x00002340 | 10 | sym.imp.textdomain |\n| sym.imp.fclose | 10 | 0x00002350 | COMPLETE | 1.000000 | 0x00002350 | 10 | sym.imp.fclose |\n| sym.imp.bindtextdomain | 10 | 0x00002360 | COMPLETE | 1.000000 | 0x00002360 | 10 | sym.imp.bindtextdomain |\n| sym.imp.dcgettext | 10 | 0x00002370 | COMPLETE | 1.000000 | 0x00002370 | 10 | sym.imp.dcgettext |\n| sym.imp.__ctype_get_mb_cur_max | 10 | 0x00002380 | COMPLETE | 1.000000 | 0x00002380 | 10 | sym.imp.__ctype_get_mb_cur_max |\n| sym.imp.strlen | 10 | 0x00002390 | COMPLETE | 1.000000 | 0x00002390 | 10 | sym.imp.strlen |\n| sym.imp.__stack_chk_fail | 10 | 0x000023a0 | COMPLETE | 1.000000 | 0x000023a0 | 10 | sym.imp.__stack_chk_fail |\n| sym.imp.strrchr | 10 | 0x000023b0 | COMPLETE | 1.000000 | 0x000023b0 | 10 | sym.imp.strrchr |\n| sym.imp.lseek | 10 | 0x000023c0 | COMPLETE | 1.000000 | 0x000023c0 | 10 | sym.imp.lseek |\n| sym.imp.memset | 10 | 0x000023d0 | COMPLETE | 1.000000 | 0x000023d0 | 10 | sym.imp.memset |\n| sym.imp.mbrtoc32 | 10 | 0x000023e0 | COMPLETE | 1.000000 | 0x000023e0 | 10 | sym.imp.mbrtoc32 |\n| sym.imp.memcmp | 10 | 0x000023f0 | COMPLETE | 1.000000 | 0x000023f0 | 10 | sym.imp.memcmp |\n| sym.imp.fputs_unlocked | 10 | 0x00002400 | COMPLETE | 1.000000 | 0x00002400 | 10 | sym.imp.fputs_unlocked |\n| sym.imp.calloc | 10 | 0x00002410 | COMPLETE | 1.000000 | 0x00002410 | 10 | sym.imp.calloc |\n| sym.imp.strcmp | 10 | 0x00002420 | COMPLETE | 1.000000 | 0x00002420 | 10 | sym.imp.strcmp |\n| sym.imp.fputc_unlocked | 10 | 0x00002430 | COMPLETE | 1.000000 | 0x00002430 | 10 | sym.imp.fputc_unlocked |\n| sym.imp.memcpy | 10 | 0x00002440 | COMPLETE | 1.000000 | 0x00002440 | 10 | sym.imp.memcpy |\n| sym.imp.fileno | 10 | 0x00002450 | COMPLETE | 1.000000 | 0x00002450 | 10 | sym.imp.fileno |\n| sym.imp.malloc | 10 | 0x00002460 | COMPLETE | 1.000000 | 0x00002460 | 10 | sym.imp.malloc |\n| sym.imp.nl_langinfo | 10 | 0x00002480 | COMPLETE | 1.000000 | 0x00002480 | 10 | sym.imp.nl_langinfo |\n| sym.imp.__freading | 10 | 0x00002490 | COMPLETE | 1.000000 | 0x00002490 | 10 | sym.imp.__freading |\n| sym.imp.realloc | 10 | 0x000024a0 | COMPLETE | 1.000000 | 0x000024a0 | 10 | sym.imp.realloc |\n| sym.imp.setlocale | 10 | 0x000024b0 | COMPLETE | 1.000000 | 0x000024b0 | 10 | sym.imp.setlocale |\n| sym.imp.__printf_chk | 10 | 0x000024c0 | COMPLETE | 1.000000 | 0x000024c0 | 10 | sym.imp.__printf_chk |\n| sym.imp.error | 10 | 0x000024d0 | COMPLETE | 1.000000 | 0x000024d0 | 10 | sym.imp.error |\n| sym.imp.exit | 10 | 0x00002500 | COMPLETE | 1.000000 | 0x00002500 | 10 | sym.imp.exit |\n| sym.imp.fwrite | 10 | 0x00002510 | COMPLETE | 1.000000 | 0x00002510 | 10 | sym.imp.fwrite |\n| sym.imp.__fprintf_chk | 10 | 0x00002520 | COMPLETE | 1.000000 | 0x00002520 | 10 | sym.imp.__fprintf_chk |\n| sym.imp.mbsinit | 10 | 0x00002530 | COMPLETE | 1.000000 | 0x00002530 | 10 | sym.imp.mbsinit |\n| sym.imp.iswprint | 10 | 0x00002540 | COMPLETE | 1.000000 | 0x00002540 | 10 | sym.imp.iswprint |\n| sym.imp.__ctype_b_loc | 10 | 0x00002550 | COMPLETE | 1.000000 | 0x00002550 | 10 | sym.imp.__ctype_b_loc |\n| fcn.000026b0 | 34 | 0x000026b0 | COMPLETE | 1.000000 | 0x000026b0 | 34 | fcn.000026b0 |\n| fcn.00002770 | 833 | 0x00002770 | PARTIAL | 0.979592 | 0x00002770 | 833 | fcn.00002770 |\n| fcn.00002ba0 | 166 | 0x00002ba0 | PARTIAL | 0.993976 | 0x00002ba0 | 166 | fcn.00002ba0 |\n| fcn.00002c50 | 79 | 0x00002c50 | PARTIAL | 0.987342 | 0x00002c50 | 79 | fcn.00002c50 |\n| fcn.00002cb0 | 220 | 0x00002cb0 | PARTIAL | 0.972727 | 0x00002cb0 | 220 | fcn.00002cb0 |\n| fcn.00002da0 | 5447 | 0x00002da0 | PARTIAL | 0.998348 | 0x00002da0 | 5447 | fcn.00002da0 |\n| fcn.00004370 | 486 | 0x00004370 | COMPLETE | 1.000000 | 0x00004370 | 486 | fcn.00004370 |\n| fcn.00004c20 | 120 | 0x00004c20 | COMPLETE | 1.000000 | 0x00004c20 | 120 | fcn.00004c20 |\n| fcn.00005070 | 1092 | 0x00005070 | PARTIAL | 0.991758 | 0x00005070 | 1092 | fcn.00005070 |\n| fcn.000055c0 | 210 | 0x000055c0 | COMPLETE | 1.000000 | 0x000055c0 | 210 | fcn.000055c0 |\n| fcn.000057f0 | 28 | 0x000057f0 | COMPLETE | 1.000000 | 0x000057f0 | 28 | fcn.000057f0 |\n| fcn.00005a80 | 241 | 0x00005a80 | COMPLETE | 1.000000 | 0x00005a80 | 241 | fcn.00005a80 |\n| fcn.00005c20 | 54 | 0x00005c20 | COMPLETE | 1.000000 | 0x00005c20 | 54 | fcn.00005c20 |\n| fcn.00005d20 | 56 | 0x00005d20 | PARTIAL | 0.964286 | 0x00005d20 | 56 | fcn.00005d20 |\n| fcn.00005d60 | 93 | 0x00005d60 | COMPLETE | 1.000000 | 0x00005d60 | 93 | fcn.00005d60 |\n| fcn.00005dc0 | 88 | 0x00005dc0 | COMPLETE | 1.000000 | 0x00005dc0 | 88 | fcn.00005dc0 |\n| fcn.00005e20 | 124 | 0x00005e20 | COMPLETE | 1.000000 | 0x00005e20 | 124 | fcn.00005e20 |\n| fcn.00005eb0 | 63 | 0x00005eb0 | COMPLETE | 1.000000 | 0x00005eb0 | 63 | fcn.00005eb0 |\n| fcn.00005ef0 | 109 | 0x00005ef0 | COMPLETE | 1.000000 | 0x00005ef0 | 109 | fcn.00005ef0 |\n| fcn.00005f70 | 54 | 0x00005f70 | PARTIAL | 0.962963 | 0x00005f70 | 54 | fcn.00005f70 |\n| fcn.00005fb0 | 180 | 0x00005fb0 | PARTIAL | 0.994444 | 0x00005fb0 | 180 | fcn.00005fb0 |\n| fcn.00006070 | 116 | 0x00006070 | COMPLETE | 1.000000 | 0x00006070 | 116 | fcn.00006070 |\n| fcn.000060f0 | 128 | 0x000060f0 | COMPLETE | 1.000000 | 0x000060f0 | 128 | fcn.000060f0 |\n| fcn.000061b0 | 18 | 0x000061b0 | COMPLETE | 1.000000 | 0x000061b0 | 18 | fcn.000061b0 |\n`-----------------------------------------------------------------------------------------------------------------------------------'\n\n\n89.2.4 Diffing classes in binaries:\nrz-diff -t classes /usr/bin/true /usr/bin/false\n--- /usr/bin/true\n+++ /usr/bin/false\n\n\n89.2.5 Commands\n\n\n89.2.6 Diffing entries in binaries\nrz-diff -t entries /usr/bin/true /usr/bin/false\n--- /usr/bin/true\n+++ /usr/bin/false\n\n\n89.2.7 Diffing fields in binaries:\nrz-diff -t fields /usr/bin/true /usr/bin/false\n--- /usr/bin/true\n+++ /usr/bin/false\n\n\n89.2.8 Diffing sections in binaries:\nrz-diff -t sections /usr/bin/true /usr/bin/false\n--- /usr/bin/true\n+++ /usr/bin/false\n\n\n89.2.9 Diffing strings in binaries:\nrz-diff -t strings /usr/bin/true /usr/bin/false\n--- /usr/bin/true\n+++ /usr/bin/false\n@@ -10,7 +10,7 @@\n --help display this help and exit\n\n Written by %s, %s, %s,\n%s, %s, %s, %s,\nand %s.\n\n Copyright %s %d Free Software Foundation, Inc.\n-Exit with a status code indicating success.\n+Exit with a status code indicating failure.\n Written by %s, %s, %s,\n%s, %s, %s, and %s.\n\n Written by %s, %s, %s,\n%s, %s, and %s.\n\n https://www.gnu.org/software/coreutils/\n@@ -59,6 +59,6 @@\n ASCII\n POSIX\n UTF-8\n+false\n shell\n %s\n\n\n-true\n\n\n\n89.2.10 Diffing symbols in binaries:\nrz-diff -t symbols /usr/bin/true /usr/bin/false\n--- /usr/bin/true\n+++ /usr/bin/false", "crumbs": [ "Command Line Tools", - "88  Rz-Diff (binary and text diffing utility)" + "89  Rz-Diff (binary and text diffing utility)" ] }, { "objectID": "src/tools/rz-asm/intro.html", "href": "src/tools/rz-asm/intro.html", - "title": "89  Rz-asm", + "title": "90  Rz-asm", "section": "", - "text": "rz-asm is an inline assembler/disassembler. Its main function is to get bytes corresponding to given machine instruction opcode.\n$ rz-asm -h\nUsage: rz-asm [-ACdDehLBvw] [-a arch] [-b bits] [-o addr] [-s syntax]\n [-f file] [-F fil:ter] [-i skip] [-l len] 'code'|hex|-\n -a [arch] Set architecture to assemble/disassemble (see -L)\n -A Show Analysis information from given hexpairs\n -b [bits] Set cpu register size (8, 16, 32, 64) (RZ_ASM_BITS)\n -B Binary input/output (-l is mandatory for binary input)\n -c [cpu] Select specific CPU (depends on arch)\n -C Output in C format\n -d, -D Disassemble from hexpair bytes (-D show hexpairs)\n -e Use big endian instead of little endian\n -I Display lifted RzIL code (same input as in -d, IL is also validated)\n -E Display ESIL expression (same input as in -d)\n -f [file] Read data from file\n -F [in:out] Specify input and/or output filters (att2intel, x86.pseudo, ...)\n -h, -hh Show this help, -hh for long\n -i [len] Ignore N bytes of the input buffer\n -j Output in JSON format\n -k [kernel] Select operating system (linux, windows, darwin, ..)\n -l [len] Input/Output length\n -L List Asm plugins: (a=asm, d=disasm, A=analyze, e=ESIL)\n -o, -@ [addr] Set start address for code (default 0)\n -O [file] Output file name (rz-asm -Bf a.asm -O a)\n -p Run SPP over input for assembly\n -q Quiet mode\n -r Output in rizin commands\n -s [syntax] Select syntax (intel, att)\n -v Show version information\n -x Use hex dwords instead of hex pairs when assembling.\n -w Describe opcode\n If '-l' value is greater than output length, output is padded with nops\n If the last argument is '-' reads from stdin\nEnvironment:\n RZ_NOPLUGINS do not load shared plugins (speedup loading)\n RZ_ASM_ARCH same as rz-asm -a\n RZ_ASM_BITS same as rz-asm -b\n RZ_DEBUG if defined, show error messages and crash signal\nPlugins for supported target architectures can be listed with the -L option. Knowing a plugin name, you can use it by specifying its name to the -a option\n$ rz-asm -L\n_dAe 8 16 6502 LGPL3 6502/NES/C64/Tamagotchi/T-1000 CPU\nadAe 8 8051 PD 8051 Intel CPU\n_dA_ 32 amd29k LGPL3 AMD 29k RISC CPU (by deroad)\na___ 16 32 64 arm.as LGPL3 as ARM Assembler (use RZ_ARM32_AS and RZ_ARM64_AS environment) (by pancake)\nadAe 16 32 64 arm BSD Capstone ARM disassembler\nadAe 8 16 avr LGPL3 AVR Atmel\nadA_ 16 32 64 bf LGPL3 Brainfuck (by pancake, nibble) v4.0.0\n_dA_ 32 chip8 LGPL3 Chip8 disassembler\n_dA_ 16 32 64 cil LGPL3 .NET Common Intermediate Language\n_dA_ 16 cr16 LGPL3 cr16 disassembly plugin\nadA_ 32 64 dalvik LGPL3 AndroidVM Dalvik\nad__ 16 dcpu16 PD Mojang's DCPU-16\n_dA_ 32 64 ebc LGPL3 EFI Bytecode (by Fedor Sakharov)\nadAe 16 gb LGPL3 GameBoy(TM) (z80-like) (by condret)\n_dAe 16 h8300 LGPL3 H8/300 disassembly plugin\n_dA_ 32 hexagon LGPL3 Qualcomm Hexagon (QDSP6) V6 (by Rot127)\n_dA_ 4 i4004 LGPL3 Intel 4004 microprocessor\n_dA_ 8 i8080 BSD Intel 8080 CPU\nadA_ 32 java LGPL-3 Java bytecode disassembler (by deroad)\n_d__ 8 lh5801 LGPL3 SHARP LH5801 disassembler\n_d__ 32 lm32 BSD disassembly plugin for Lattice Micro 32 ISA (by Felix Held)\nadA_ 8 luac LGPL3 luac disassemble plugin\n_dA_ 32 m68k BSD Capstone M68K disassembler\n_dA_ 8 32 m680x BSD Capstone M680X Disassembler\n_dA_ 32 malbolge LGPL3 Malbolge Ternary VM (by condret)\n_dA_ 32 mcore LGPL3 Motorola MCORE disassembler\n_d__ 16 mcs96 LGPL3 condrets car\nadAe 16 32 64 mips BSD Capstone MIPS disassembler\n_dA_ 16 msp430 LGPL3 msp430 disassembly plugin\nadA_ 16 32 64 null MIT no disassemble (by pancake) v1.0.0\n_dA_ 32 or1k LGPL3 OpenRISC 1000\n_dAe 8 pic LGPL3 PIC disassembler\na___ 32 64 ppc.as LGPL3 as PPC Assembler (use RZ_PPC_AS environment) (by eagleoflqj)\n_dAe 32 64 ppc BSD Capstone PowerPC disassembler (by pancake)\n_dA_ 32 propeller LGPL3 propeller disassembly plugin\n_dA_ 8 16 pyc LGPL3 PYC disassemble plugin\nadA_ 32 rl78 LGPL3 Renesas RL78 disassembler (by Bastian Engel)\n_dA_ 32 rsp LGPL3 Reality Signal Processor\n_dA_ 32 rx LGPL3 Renesas RX Family disassembler (by Heersin)\nadAe 32 sh LGPL3 SuperH-4 CPU (by DMaroo)\n_dA_ 8 16 snes LGPL3 SuperNES CPU\n_dA_ 32 64 sparc BSD Capstone SPARC disassembler\n_dA_ 16 spc700 LGPL3 spc700, snes' sound-chip\n_dA_ 32 64 sysz BSD SystemZ CPU disassembler\n_dA_ 32 tms320 LGPLv3 TMS320 DSP family (c54x,c55x,c55x+,c64x)\n_d__ 32 tms320c64x BSD Capstone TMS320c64x disassembler\n_dAe 32 v810 LGPL3 v810 disassembly plugin (by pancake)\n_dAe 32 v850 LGPL3 v850 disassembly plugin\nadA_ 32 wasm MIT WebAssembly (by cgvwzq) v0.1.0\na___ 16 32 64 x86.as LGPL3 Intel X86 GNU Assembler (Use RZ_X86_AS env)\n_dAe 16 32 64 x86 BSD Capstone X86 disassembler\na___ 16 32 64 x86.nasm LGPL3 X86 nasm assembler\na___ 16 32 64 x86.nz LGPL3 x86 handmade assembler\n_dA_ 16 xap PD XAP4 RISC (CSR)\n_dA_ 32 xcore BSD Capstone XCore disassembler (by pancake)\n_dAe 32 64 riscv.cs BSD Capstone RISCV disassembler\n_dA_ 32 tricore BSD Siemens TriCore CPU (by billow)\n_dA_ 16 32 arc GPL3 Argonaut RISC Core\n_dA_ 32 cris GPL3 Axis Communications 32-bit embedded processor (by pancake)\n_d__ 32 hppa GPL3 HP PA-RISC\n_d__ 32 lanai GPL3 LANAI\nadAe 32 64 mips.gnu GPL3 MIPS CPU\n_dA_ 32 nios2 GPL3 NIOS II Embedded Processor\n_dAe 32 64 riscv GPL3 RISC-V\n_dA_ 32 64 sparc.gnu GPL3 Scalable Processor Architecture\n_dA_ 8 32 vax GPL3 VAX\n_dAe 32 xtensa GPL3 XTensa CPU\nadA_ 8 z80 GPL3 Zilog Z80 (by condret)\n_dAe 8 16 32 64 ghidra LGPL3 SLEIGH Disassembler from Ghidra (by FXTi)\n\nNote that “ad” in the first column means both assembler and disassembler are offered by a corresponding plugin. “d” indicates disassembler, ”a” means only assembler is available.", + "text": "rz-asm is an inline assembler/disassembler. Its main function is to get bytes corresponding to given machine instruction opcode.\nUsage: rz-asm [-ACdDehLBvw] [-a arch] [-b bits] [-o addr] [-s syntax]\n [-f file] [-F fil:ter] [-i skip] [-l len] 'code'|hex|-\n -a [arch] Set architecture to assemble/disassemble (see -L)\n -A Show Analysis information from given hexpairs\n -b [bits] Set cpu register size (8, 16, 32, 64) (RZ_ASM_BITS)\n -B Binary input/output (-l is mandatory for binary input)\n -c [cpu] Select specific CPU (depends on arch)\n -C Output in C format\n -d, -D Disassemble from hexpair bytes (-D show hexpairs)\n -e Use big endian instead of little endian\n -I Display lifted RzIL code (same input as in -d, IL is also validated)\n -E Display ESIL expression (same input as in -d)\n -f [file] Read data from file\n -F [in:out] Specify input and/or output filters (att2intel, x86.pseudo, ...)\n -h, -hh Show this help, -hh for long\n -i [len] Ignore N bytes of the input buffer\n -j Output in JSON format\n -k [kernel] Select operating system (linux, windows, darwin, ..)\n -l [len] Input/Output length\n -L List Asm plugins: (a=asm, d=disasm, A=analyze, e=ESIL)\n -o, -@ [addr] Set start address for code (default 0)\n -O [file] Output file name (rz-asm -Bf a.asm -O a)\n -p Run SPP over input for assembly\n -q Quiet mode\n -r Output in rizin commands\n -s [syntax] Select syntax (intel, att)\n -v Show version information\n -x Use hex dwords instead of hex pairs when assembling.\n -w Describe opcode\n If '-l' value is greater than output length, output is padded with nops\n If the last argument is '-' reads from stdin\nEnvironment:\n RZ_ARCH e asm.arch # architecture to assemble/disassemble (same as rz-asm -a)\n RZ_ASM_ARCH # architecture to assemble/disassemble (same as rz-asm -a)\n RZ_ASM_BITS # cpu register size (8, 16, 32, 64) (same as rz-asm -b)\n RZ_BITS e asm.bits # cpu register size (8, 16, 32, 64) (same as rz-asm -b)\n RZ_DEBUG # if defined, show error messages and crash signal\n RZ_NOPLUGINS # do not load shared plugins (speedup loading)\nPlugins for supported target architectures can be listed with the -L option. Knowing a plugin name, you can use it by specifying its name to the -a option\n$ rz-asm -L\n_dAe 8 16 6502 LGPL3 6502/NES/C64/Tamagotchi/T-1000 CPU\nadAe 8 8051 PD 8051 Intel CPU\n_dA_ 32 amd29k LGPL3 AMD 29k RISC CPU (by deroad)\na___ 16 32 64 arm.as LGPL3 as ARM Assembler (use RZ_ARM32_AS and RZ_ARM64_AS environment) (by pancake)\nadAe 16 32 64 arm BSD Capstone ARM disassembler\nadAe 8 16 avr LGPL3 AVR Atmel\nadA_ 16 32 64 bf LGPL3 Brainfuck (by pancake, nibble) v4.0.0\n_dA_ 32 chip8 LGPL3 Chip8 disassembler\n_dA_ 16 32 64 cil LGPL3 .NET Common Intermediate Language\n_dA_ 16 cr16 LGPL3 cr16 disassembly plugin\nadA_ 32 64 dalvik LGPL3 AndroidVM Dalvik\nad__ 16 dcpu16 PD Mojang's DCPU-16\n_dA_ 32 64 ebc LGPL3 EFI Bytecode (by Fedor Sakharov)\nadAe 16 gb LGPL3 GameBoy(TM) (z80-like) (by condret)\n_dAe 16 h8300 LGPL3 H8/300 disassembly plugin\n_dA_ 32 hexagon LGPL3 Qualcomm Hexagon (QDSP6) V6 (by Rot127)\n_dA_ 4 i4004 LGPL3 Intel 4004 microprocessor\n_dA_ 8 i8080 BSD Intel 8080 CPU\nadA_ 32 java LGPL-3 Java bytecode disassembler (by deroad)\n_d__ 8 lh5801 LGPL3 SHARP LH5801 disassembler\n_d__ 32 lm32 BSD disassembly plugin for Lattice Micro 32 ISA (by Felix Held)\nadA_ 8 luac LGPL3 luac disassemble plugin\n_dA_ 32 m68k BSD Capstone M68K disassembler\n_dA_ 8 32 m680x BSD Capstone M680X Disassembler\n_dA_ 32 malbolge LGPL3 Malbolge Ternary VM (by condret)\n_dA_ 32 mcore LGPL3 Motorola MCORE disassembler\n_d__ 16 mcs96 LGPL3 condrets car\nadAe 16 32 64 mips BSD Capstone MIPS disassembler\n_dA_ 16 msp430 LGPL3 msp430 disassembly plugin\nadA_ 16 32 64 null MIT no disassemble (by pancake) v1.0.0\n_dA_ 32 or1k LGPL3 OpenRISC 1000\n_dAe 8 pic LGPL3 PIC disassembler\na___ 32 64 ppc.as LGPL3 as PPC Assembler (use RZ_PPC_AS environment) (by eagleoflqj)\n_dAe 32 64 ppc BSD Capstone PowerPC disassembler (by pancake)\n_dA_ 32 propeller LGPL3 propeller disassembly plugin\n_dA_ 8 16 pyc LGPL3 PYC disassemble plugin\nadA_ 32 rl78 LGPL3 Renesas RL78 disassembler (by Bastian Engel)\n_dA_ 32 rsp LGPL3 Reality Signal Processor\n_dA_ 32 rx LGPL3 Renesas RX Family disassembler (by Heersin)\nadAe 32 sh LGPL3 SuperH-4 CPU (by DMaroo)\n_dA_ 8 16 snes LGPL3 SuperNES CPU\n_dA_ 32 64 sparc BSD Capstone SPARC disassembler\n_dA_ 16 spc700 LGPL3 spc700, snes' sound-chip\n_dA_ 32 64 sysz BSD SystemZ CPU disassembler\n_dA_ 32 tms320 LGPLv3 TMS320 DSP family (c54x,c55x,c55x+,c64x)\n_d__ 32 tms320c64x BSD Capstone TMS320c64x disassembler\n_dAe 32 v810 LGPL3 v810 disassembly plugin (by pancake)\n_dAe 32 v850 LGPL3 v850 disassembly plugin\nadA_ 32 wasm MIT WebAssembly (by cgvwzq) v0.1.0\na___ 16 32 64 x86.as LGPL3 Intel X86 GNU Assembler (Use RZ_X86_AS env)\n_dAe 16 32 64 x86 BSD Capstone X86 disassembler\na___ 16 32 64 x86.nasm LGPL3 X86 nasm assembler\na___ 16 32 64 x86.nz LGPL3 x86 handmade assembler\n_dA_ 16 xap PD XAP4 RISC (CSR)\n_dA_ 32 xcore BSD Capstone XCore disassembler (by pancake)\n_dAe 32 64 riscv.cs BSD Capstone RISCV disassembler\n_dA_ 32 tricore BSD Siemens TriCore CPU (by billow)\n_dA_ 16 32 arc GPL3 Argonaut RISC Core\n_dA_ 32 cris GPL3 Axis Communications 32-bit embedded processor (by pancake)\n_d__ 32 hppa GPL3 HP PA-RISC\n_d__ 32 lanai GPL3 LANAI\nadAe 32 64 mips.gnu GPL3 MIPS CPU\n_dA_ 32 nios2 GPL3 NIOS II Embedded Processor\n_dAe 32 64 riscv GPL3 RISC-V\n_dA_ 32 64 sparc.gnu GPL3 Scalable Processor Architecture\n_dA_ 8 32 vax GPL3 VAX\n_dAe 32 xtensa GPL3 XTensa CPU\nadA_ 8 z80 GPL3 Zilog Z80 (by condret)\n_dAe 8 16 32 64 ghidra LGPL3 SLEIGH Disassembler from Ghidra (by FXTi)\n\nNote that “ad” in the first column means both assembler and disassembler are offered by a corresponding plugin. “d” indicates disassembler, ”a” means only assembler is available.", "crumbs": [ "Command Line Tools", - "89  Rz-asm" + "90  Rz-asm" ] }, { "objectID": "src/tools/rz-asm/assemble.html", "href": "src/tools/rz-asm/assemble.html", - "title": "90  Assembler", + "title": "91  Assembler", "section": "", - "text": "Assembling is the action to take a computer instruction in human-readable form (using mnemonics) and convert that into a bunch of bytes that can be executed by a machine.\nIn Rizin, the assembler and disassembler logic is implemented in the rz_asm_* API, and can be used with the pa and pad commands from the commandline as well as using rz-asm.\nRz-asm can be used to quickly copy-paste hexpairs that represent a given machine instruction. The following line is assembling this mov instruction for x86/32.\n$ rz-asm -a x86 -b 32 'mov eax, 33'\nb821000000\nApart from the specifying the input as an argument, you can also pipe it to rz-asm:\n$ echo 'push eax;nop;nop' | rz-asm -f -\n5090\nAs you have seen, rz-asm can assemble one or many instructions. In line by separating them with a semicolon ;, but can also read that from a file, using generic nasm/gas/.. syntax and directives. You can check the rz-asm manpage for more details on this.\nThe pa and pad are a subcommands of print, what means they will only print assembly or disassembly. In case you want to actually write the instruction it is required to use wa or wx commands with the assembly string or bytes appended.\nThe assembler understands the following input languages and their flavors: x86 (Intel and AT&T variants), olly (OllyDBG syntax), powerpc (PowerPC), arm and java. For Intel syntax, rz-asm tries to mimic NASM or GAS.\nThere are several examples in the rz-asm source code directory. Consult them to understand how you can assemble a raw binary file from a rz-asm description.\nLet’s create an assembly file called selfstop.rzasm:\n;\n; Self-Stop shellcode written in rz-asm for x86\n;\n; --pancake\n;\n\n.arch x86\n.equ base 0x8048000\n.org 0x8048000 ; the offset where we inject the 5 byte jmp\n\nselfstop:\n push 0x8048000\n pusha\n mov eax, 20\n int 0x80\n\n mov ebx, eax\n mov ecx, 19\n mov eax, 37\n int 0x80\n popa\n ret\n;\n; The call injection\n;\n\n ret\nNow we can assemble it in place:\n[0x00000000]> e asm.bits=32\n[0x00000000]> wx `!rz-asm -f a.rzasm`\n[0x00000000]> pd 20\n 0x00000000 6800800408 push 0x8048000 ; 0x08048000\n 0x00000005 60 pushad\n 0x00000006 b814000000 mov eax, 0x14 ; 0x00000014\n 0x0000000b cd80 int 0x80\n syscall[0x80][0]=?\n 0x0000000d 89c3 mov ebx, eax\n 0x0000000f b913000000 mov ecx, 0x13 ; 0x00000013\n 0x00000014 b825000000 mov eax, 0x25 ; 0x00000025\n 0x00000019 cd80 int 0x80\n syscall[0x80][0]=?\n 0x0000001b 61 popad\n 0x0000001c c3 ret\n 0x0000001d c3 ret\n\n90.0.1 Visual mode\nAssembling also is accessible in Rizin visual mode through pressing A key to insert the assembly in the current offset.\nThe cool thing of writing assembly using the visual assembler interface that the changes are done in memory until you press enter.\nSo you can check the size of the code and which instructions is overlapping before committing the changes.", + "text": "Assembling is the action to take a computer instruction in human-readable form (using mnemonics) and convert that into a bunch of bytes that can be executed by a machine.\nIn Rizin, the assembler and disassembler logic is implemented in the rz_asm_* API, and can be used with the pa and pad commands from the commandline as well as using rz-asm.\nRz-asm can be used to quickly copy-paste hexpairs that represent a given machine instruction. The following line is assembling this mov instruction for x86/32.\n$ rz-asm -a x86 -b 32 'mov eax, 33'\nb821000000\nApart from the specifying the input as an argument, you can also pipe it to rz-asm:\n$ echo 'push eax;nop;nop' | rz-asm -f -\n5090\nAs you have seen, rz-asm can assemble one or many instructions. In line by separating them with a semicolon ;, but can also read that from a file, using generic nasm/gas/.. syntax and directives. You can check the rz-asm manpage for more details on this.\nThe pa and pad are a subcommands of print, what means they will only print assembly or disassembly. In case you want to actually write the instruction it is required to use wa or wx commands with the assembly string or bytes appended.\nThe assembler understands the following input languages and their flavors: x86 (Intel and AT&T variants), olly (OllyDBG syntax), powerpc (PowerPC), arm and java. For Intel syntax, rz-asm tries to mimic NASM or GAS.\nThere are several examples in the rz-asm source code directory. Consult them to understand how you can assemble a raw binary file from a rz-asm description.\nLet’s create an assembly file called selfstop.rzasm:\n;\n; Self-Stop shellcode written in rz-asm for x86\n;\n; --pancake\n;\n\n.arch x86\n.equ base 0x8048000\n.org 0x8048000 ; the offset where we inject the 5 byte jmp\n\nselfstop:\n push 0x8048000\n pusha\n mov eax, 20\n int 0x80\n\n mov ebx, eax\n mov ecx, 19\n mov eax, 37\n int 0x80\n popa\n ret\n;\n; The call injection\n;\n\n ret\nNow we can assemble it in place:\n[0x00000000]> e asm.bits=32\n[0x00000000]> wx `!rz-asm -f a.rzasm`\n[0x00000000]> pd 20\n 0x00000000 6800800408 push 0x8048000 ; 0x08048000\n 0x00000005 60 pushad\n 0x00000006 b814000000 mov eax, 0x14 ; 0x00000014\n 0x0000000b cd80 int 0x80\n syscall[0x80][0]=?\n 0x0000000d 89c3 mov ebx, eax\n 0x0000000f b913000000 mov ecx, 0x13 ; 0x00000013\n 0x00000014 b825000000 mov eax, 0x25 ; 0x00000025\n 0x00000019 cd80 int 0x80\n syscall[0x80][0]=?\n 0x0000001b 61 popad\n 0x0000001c c3 ret\n 0x0000001d c3 ret\n\n91.0.1 Visual mode\nAssembling also is accessible in Rizin visual mode through pressing A key to insert the assembly in the current offset.\nThe cool thing of writing assembly using the visual assembler interface that the changes are done in memory until you press enter.\nSo you can check the size of the code and which instructions is overlapping before committing the changes.", "crumbs": [ "Command Line Tools", - "90  Assembler" + "91  Assembler" ] }, { "objectID": "src/tools/rz-asm/disassemble.html", "href": "src/tools/rz-asm/disassemble.html", - "title": "91  Disassembler", + "title": "92  Disassembler", "section": "", - "text": "91.0.1 pd N\nDisassembling is the inverse action of assembling. Rz-asm takes hexpair as an input (but can also take a file in binary form) and show the human-readable form.\nTo do this we can use the -d option of rz-asm like this:\nRz-asm also has the -D flag to show the disassembly like -d does, but includes offset and bytes.\nIn Rizin there are many commands to perform a disassembly from a specific place in memory.\nYou might be interested in trying if you want different outputs for later parsing with your scripts, or just grep to find what you are looking for:\nDisassemble N instructions", + "text": "92.0.1 pd N\nDisassembling is the inverse action of assembling. Rz-asm takes hexpair as an input (but can also take a file in binary form) and show the human-readable form.\nTo do this we can use the -d option of rz-asm like this:\nRz-asm also has the -D flag to show the disassembly like -d does, but includes offset and bytes.\nIn Rizin there are many commands to perform a disassembly from a specific place in memory.\nYou might be interested in trying if you want different outputs for later parsing with your scripts, or just grep to find what you are looking for:\nDisassemble N instructions", "crumbs": [ "Command Line Tools", - "91  Disassembler" + "92  Disassembler" ] }, { "objectID": "src/tools/rz-asm/disassemble.html#pi-pi", "href": "src/tools/rz-asm/disassemble.html#pi-pi", - "title": "91  Disassembler", - "section": "91.1 pi, pI", - "text": "91.1 pi, pI\nSame as pd and pD, but using a simpler output.", + "title": "92  Disassembler", + "section": "92.1 pi, pI", + "text": "92.1 pi, pI\nSame as pd and pD, but using a simpler output.", "crumbs": [ "Command Line Tools", - "91  Disassembler" + "92  Disassembler" ] }, { "objectID": "src/tools/rz-asm/config.html", "href": "src/tools/rz-asm/config.html", - "title": "92  Disassembler Configuration", + "title": "93  Disassembler Configuration", "section": "", "text": "The assembler and disassembler have many small switches to tweak the output.\nThose configurations are available through the e command. Here there are the most common ones:\n\nasm.bytes: Show/hide bytes\nasm.offset: Show/hide offset\nasm.lines: Show/hide lines\nasm.ucase: Show disasm in uppercase\n…\n\nUse the el asm. for more details.", "crumbs": [ "Command Line Tools", - "92  Disassembler Configuration" + "93  Disassembler Configuration" ] }, { "objectID": "src/tools/rz-gg/rz-gg.html", "href": "src/tools/rz-gg/rz-gg.html", - "title": "93  Rz-gg", + "title": "94  Rz-gg", "section": "", - "text": "93.1 Compiling rz-gg example\nrz-gg stands for rizin egg, this is the basic block to construct relocatable snippets of code to be used for injection in target processes when doing exploiting.\nrz-gg compiles programs written in a simple high-level language into tiny binaries for x86, x86-64, and ARM.\nYou can also access all the rz-gg commands from the rizin shell. They are present under g. See g? for more information about how to use them.\nBy default, it will compile its own rz-gg language, but you can also compile C code using GCC or Clang shellcodes depending on the file extension. Let’s create C file called helloworld.c:\nYou can also compile for ARM. For that, specify the architecture as arm:", + "text": "94.1 Compiling rz-gg example\nrz-gg stands for rizin egg, this is the basic block to construct relocatable snippets of code to be used for injection in target processes when doing exploiting.\nrz-gg compiles programs written in a simple high-level language into tiny binaries for x86, x86-64, and ARM.\nYou can also access all the rz-gg commands from the rizin shell. They are present under g. See g? for more information about how to use them.\nBy default, it will compile its own rz-gg language, but you can also compile C code using GCC or Clang shellcodes depending on the file extension. Let’s create C file called helloworld.c:\nYou can also compile for ARM. For that, specify the architecture as arm:", "crumbs": [ "Command Line Tools", - "93  Rz-gg" + "94  Rz-gg" ] }, { "objectID": "src/tools/rz-gg/rz-gg.html#compiling-rz-gg-example", "href": "src/tools/rz-gg/rz-gg.html#compiling-rz-gg-example", - "title": "93  Rz-gg", + "title": "94  Rz-gg", "section": "", "text": "$ cat hello.r\nexit@syscall(1);\n\nmain@global() {\n exit(2);\n}\n\n$ rz-gg -a x86 -b 64 hello.r\n48c7c00200000050488b3c2448c7c0010000000f054883c408c3\n0x00000000 1 48 dec eax\n0x00000001 6 c7c002000000 mov eax, 2\n0x00000007 1 50 push eax\n0x00000008 1 48 dec eax\n0x00000009 3 8b3c24 mov edi, dword [esp]\n0x0000000c 1 48 dec eax\n0x0000000d 6 c7c001000000 mov eax, 1\n0x00000013 2 0f05 syscall\n0x00000015 1 48 dec eax\n0x00000016 3 83c408 add esp, 8\n0x00000019 1 c3 ret\n\n$ rz-asm -a x86 -b 64 -D 48c7c00200000050488b3c2448c7c0010000000f054883c408c3\n0x00000000 7 48c7c002000000 mov rax, 2\n0x00000007 1 50 push rax\n0x00000008 4 488b3c24 mov rdi, qword [rsp]\n0x0000000c 7 48c7c001000000 mov rax, 1\n0x00000013 2 0f05 syscall\n0x00000015 4 4883c408 add rsp, 8\n0x00000019 1 c3 ret\n\n$ rz-gg -a arm -b 32 hello.r\n00482de90200a0e30c008de508109de50170a0e3000000ef0088bde8\n\n$ rz-asm -a arm -b 32 -D 00482de90200a0e30c008de508109de50170a0e3000000ef0088bde8\n0x00000000 4 00482de9 push {fp, lr}\n0x00000004 4 0200a0e3 mov r0, 2\n0x00000008 4 0c008de5 str r0, [sp, 0xc]\n0x0000000c 4 08109de5 ldr r1, [sp, 8]\n0x00000010 4 0170a0e3 mov r7, 1\n0x00000014 4 000000ef svc 0\n0x00000018 4 0088bde8 pop {fp, pc}", "crumbs": [ "Command Line Tools", - "93  Rz-gg" + "94  Rz-gg" ] }, { "objectID": "src/tools/rz-gg/rz-gg.html#tiny-binaries", "href": "src/tools/rz-gg/rz-gg.html#tiny-binaries", - "title": "93  Rz-gg", - "section": "93.2 Tiny binaries", - "text": "93.2 Tiny binaries\nYou can create tiny binaries for your code using the -F flag in rz-gg, or the -C in rz-bin.\n$ cat helloworld.r\nint main() {\n write(1, \"Hello World\\n\", 13);\n return 0;\n}\n\n$ rz-gg -O -F helloworld.c\n\n$ ./helloworld\nHello World\n\n$ wc -c < helloworld\n259\nWe can see that the size of the binary is just 259 bytes.", + "title": "94  Rz-gg", + "section": "94.2 Tiny binaries", + "text": "94.2 Tiny binaries\nYou can create tiny binaries for your code using the -F flag in rz-gg, or the -C in rz-bin.\n$ cat helloworld.r\nint main() {\n write(1, \"Hello World\\n\", 13);\n return 0;\n}\n\n$ rz-gg -O -F helloworld.c\n\n$ ./helloworld\nHello World\n\n$ wc -c < helloworld\n259\nWe can see that the size of the binary is just 259 bytes.", "crumbs": [ "Command Line Tools", - "93  Rz-gg" + "94  Rz-gg" ] }, { "objectID": "src/tools/rz-gg/rz-gg.html#output-format", "href": "src/tools/rz-gg/rz-gg.html#output-format", - "title": "93  Rz-gg", - "section": "93.3 Output format", - "text": "93.3 Output format\nYou can change the output format using the -f flag. Here’s an example of changing it to python:\n$ rz-gg -O -F -f python helloworld.r\n\n$ xxd helloworld | head -n 3\n00000000: 696d 706f 7274 2073 7472 7563 740a 6275 import struct.bu\n00000010: 6620 3d20 7374 7275 6374 2e70 6163 6b20 f = struct.pack\n00000020: 2822 3133 3942 222c 202a 5b0a 3078 3535 (\"139B\", *[.0x55\nYou can set the output format to C, PE, ELF, Mach-O, raw, python or javascript.", + "title": "94  Rz-gg", + "section": "94.3 Output format", + "text": "94.3 Output format\nYou can change the output format using the -f flag. Here’s an example of changing it to python:\n$ rz-gg -O -F -f python helloworld.r\n\n$ xxd helloworld | head -n 3\n00000000: 696d 706f 7274 2073 7472 7563 740a 6275 import struct.bu\n00000010: 6620 3d20 7374 7275 6374 2e70 6163 6b20 f = struct.pack\n00000020: 2822 3133 3942 222c 202a 5b0a 3078 3535 (\"139B\", *[.0x55\nYou can set the output format to C, PE, ELF, Mach-O, raw, python or javascript.", "crumbs": [ "Command Line Tools", - "93  Rz-gg" + "94  Rz-gg" ] }, { "objectID": "src/tools/rz-gg/lang.html", "href": "src/tools/rz-gg/lang.html", - "title": "94  Syntax of the language", + "title": "95  Syntax of the language", "section": "", - "text": "94.1 Preprocessor\nThe code of rz_egg is compiled as in a flow. It is a one-pass compiler;\nthis means that you have to define the proper stackframe size at the\nbeginning of the function, and you have to define the functions in\norder to avoid getting compilation errors.\nThe compiler generates assembly code for x86-{32,64} and arm. But it aims\nto support more platforms. This code is the compiled with rz_asm and\ninjected into a tiny binary with rz_bin.\nYou may like to use rz_egg to create standalone binaries, position-\nindependent raw eggs to be injected on running processes or to patch\non-disk binaries.\nThe generated code is not yet optimized, but it’s safe to be executed\nat any place in the code.", + "text": "95.1 Preprocessor\nThe code of rz_egg is compiled as in a flow. It is a one-pass compiler;\nthis means that you have to define the proper stackframe size at the\nbeginning of the function, and you have to define the functions in\norder to avoid getting compilation errors.\nThe compiler generates assembly code for x86-{32,64} and arm. But it aims\nto support more platforms. This code is the compiled with rz_asm and\ninjected into a tiny binary with rz_bin.\nYou may like to use rz_egg to create standalone binaries, position-\nindependent raw eggs to be injected on running processes or to patch\non-disk binaries.\nThe generated code is not yet optimized, but it’s safe to be executed\nat any place in the code.", "crumbs": [ "Command Line Tools", - "94  Syntax of the language" + "95  Syntax of the language" ] }, { "objectID": "src/tools/rz-gg/lang.html#preprocessor", "href": "src/tools/rz-gg/lang.html#preprocessor", - "title": "94  Syntax of the language", + "title": "95  Syntax of the language", "section": "", - "text": "94.1.1 Aliases\nSometimes you just need to replace at compile time a single entity on\nmultiple places. Aliases are translated into ‘equ’ statements in assembly\nlanguage. This is just an assembler-level keyword redefinition.\nAF_INET@alias(2);\nprintf@alias(0x8053940);\n\n\n94.1.2 Includes\nUse cat(1) or the preprocessor to concatenate multiple files to be compiled.\nINCDIR@alias(\"/usr/include/rz-gg\");\nsys-osx.r@include(INCDIR);\n\n\n94.1.3 Hashbang\neggs can use a hashbang to make them executable.\n$ head -n1 hello.r\n#!/usr/bin/rz-gg -X\n$ ./hello.r\nHello World!\n\n\n94.1.4 Main\nThe execution of the code is done as in a flow. The first function to be\ndefined will be the first one to be executed. If you want to run main()\njust do like this:\n#!/usr/bin/rz-gg -X\nmain();\n...\nmain@global(128,64) {\n...\n\n\n94.1.5 Function definition\nYou may like to split up your code into several code blocks. Those blocks\nare bound to a label followed by root brackets ‘{ … }’\n\n\n94.1.6 Function signatures\nname@type(stackframesize,staticframesize) { body }\nname : name of the function to define\ntype : see function types below\nstackframesize : get space from stack to store local variables\nstaticframesize : get space from stack to store static variables (strings)\nbody : code of the function\n\n\n94.1.7 Function types\nalias Used to create aliases\ndata ; the body of the block is defined in .data\ninline ; the function body is inlined when called\nglobal ; make the symbol global\nfastcall ; function that is called using the fast calling convention\nsyscall ; define syscall calling convention signature\n\n\n94.1.8 Syscalls\nr_egg offers a syntax sugar for defining syscalls. The syntax is like this:\nexit@syscall(1);\n@syscall() {\n`: mov eax,.arg```\n: int 0x80\n}\nmain@global() {\nexit (0);\n}\n\n\n94.1.9 Libraries\nAt the moment there is no support for linking r_egg programs to system\nlibraries. but if you inject the code into a program (disk/memory) you\ncan define the address of each function using the @alias syntax.\n\n\n94.1.10 Core library\nThere’s a work-in-progress libc-like library written completely in r_egg\n\n\n94.1.11 Variables\n.arg\n.arg0\n.arg1\n.arg2\n.var0\n.var2\n.fix\n.ret ; eax for x86, r0 for arm\n.bp\n.pc\n.sp\nAttention: All the numbers after .var and .arg mean the offset with the\ntop of stack, not variable symbols.\n\n\n94.1.12 Arrays\nSupported as raw pointers. TODO: enhance this feature\n\n\n94.1.13 Tracing\nSometimes r_egg programs will break or just not work as expected. Use the\n‘trace’ architecture to get a arch-backend call trace:\n$ rz-gg -a trace -s yourprogram.r\n\n\n94.1.14 Pointers\nTODO: Theoretically ‘*’ is used to get contents of a memory pointer.\n\n\n94.1.15 Virtual registers\nTODO: a0, a1, a2, a3, sp, fp, bp, pc\n\n\n94.1.16 Math operations\nrz-gg supports local variables assignment by math operating, including\nthe following operators:\n+ - * / & | ^\n\n\n94.1.17 Return values\nThe return value is stored in the a0 register, this register is set when\ncalling a function or when typing a variable name without assignment.\n$ cat test.r\nadd@global(4) {\n .var0 = .arg0 + .arg1;\n .var0;\n}\n\nmain@global() {\n add (3,4);\n}\n\n$ rz-gg -F -o test test.r\n$ ./test\n$ echo $?\n7\n\n\n94.1.18 Traps\nEach architecture have a different instruction to break the execution of\nthe program. RzEgg language captures calls to ‘break()’ to run the emit_trap\ncallback of the selected arch. The\nbreak(); –> compiles into ‘int3’ on x86\nbreak; –> compiles into ‘int3’ on x86\n\n\n94.1.19 Inline assembly\nLines prefixed with ‘:’ char are just inlined in the output assembly.\n: jmp 0x8048400\n: .byte 33,44\n\n\n94.1.20 Labels\nYou can define labels using the : keyword like this:\n:label_name:\n/* loop forever */\ngoto(label_name)\n\n\n94.1.21 Control flow\ngoto (addr) – branch execution\nwhile (cond)\nif (cond)\nif (cond) { body } else { body }\nbreak () – executes a trap instruction\n\n\n94.1.22 Comments\nSupported syntax for comments are:\n/* multiline comment */'\n// single line comment\n# single line comment", + "text": "95.1.1 Aliases\nSometimes you just need to replace at compile time a single entity on\nmultiple places. Aliases are translated into ‘equ’ statements in assembly\nlanguage. This is just an assembler-level keyword redefinition.\nAF_INET@alias(2);\nprintf@alias(0x8053940);\n\n\n95.1.2 Includes\nUse cat(1) or the preprocessor to concatenate multiple files to be compiled.\nINCDIR@alias(\"/usr/include/rz-gg\");\nsys-osx.r@include(INCDIR);\n\n\n95.1.3 Hashbang\neggs can use a hashbang to make them executable.\n$ head -n1 hello.r\n#!/usr/bin/rz-gg -X\n$ ./hello.r\nHello World!\n\n\n95.1.4 Main\nThe execution of the code is done as in a flow. The first function to be\ndefined will be the first one to be executed. If you want to run main()\njust do like this:\n#!/usr/bin/rz-gg -X\nmain();\n...\nmain@global(128,64) {\n...\n\n\n95.1.5 Function definition\nYou may like to split up your code into several code blocks. Those blocks\nare bound to a label followed by root brackets ‘{ … }’\n\n\n95.1.6 Function signatures\nname@type(stackframesize,staticframesize) { body }\nname : name of the function to define\ntype : see function types below\nstackframesize : get space from stack to store local variables\nstaticframesize : get space from stack to store static variables (strings)\nbody : code of the function\n\n\n95.1.7 Function types\nalias Used to create aliases\ndata ; the body of the block is defined in .data\ninline ; the function body is inlined when called\nglobal ; make the symbol global\nfastcall ; function that is called using the fast calling convention\nsyscall ; define syscall calling convention signature\n\n\n95.1.8 Syscalls\nr_egg offers a syntax sugar for defining syscalls. The syntax is like this:\nexit@syscall(1);\n@syscall() {\n`: mov eax,.arg```\n: int 0x80\n}\nmain@global() {\nexit (0);\n}\n\n\n95.1.9 Libraries\nAt the moment there is no support for linking r_egg programs to system\nlibraries. but if you inject the code into a program (disk/memory) you\ncan define the address of each function using the @alias syntax.\n\n\n95.1.10 Core library\nThere’s a work-in-progress libc-like library written completely in r_egg\n\n\n95.1.11 Variables\n.arg\n.arg0\n.arg1\n.arg2\n.var0\n.var2\n.fix\n.ret ; eax for x86, r0 for arm\n.bp\n.pc\n.sp\nAttention: All the numbers after .var and .arg mean the offset with the\ntop of stack, not variable symbols.\n\n\n95.1.12 Arrays\nSupported as raw pointers. TODO: enhance this feature\n\n\n95.1.13 Tracing\nSometimes r_egg programs will break or just not work as expected. Use the\n‘trace’ architecture to get a arch-backend call trace:\n$ rz-gg -a trace -s yourprogram.r\n\n\n95.1.14 Pointers\nTODO: Theoretically ‘*’ is used to get contents of a memory pointer.\n\n\n95.1.15 Virtual registers\nTODO: a0, a1, a2, a3, sp, fp, bp, pc\n\n\n95.1.16 Math operations\nrz-gg supports local variables assignment by math operating, including\nthe following operators:\n+ - * / & | ^\n\n\n95.1.17 Return values\nThe return value is stored in the a0 register, this register is set when\ncalling a function or when typing a variable name without assignment.\n$ cat test.r\nadd@global(4) {\n .var0 = .arg0 + .arg1;\n .var0;\n}\n\nmain@global() {\n add (3,4);\n}\n\n$ rz-gg -F -o test test.r\n$ ./test\n$ echo $?\n7\n\n\n95.1.18 Traps\nEach architecture have a different instruction to break the execution of\nthe program. RzEgg language captures calls to ‘break()’ to run the emit_trap\ncallback of the selected arch. The\nbreak(); –> compiles into ‘int3’ on x86\nbreak; –> compiles into ‘int3’ on x86\n\n\n95.1.19 Inline assembly\nLines prefixed with ‘:’ char are just inlined in the output assembly.\n: jmp 0x8048400\n: .byte 33,44\n\n\n95.1.20 Labels\nYou can define labels using the : keyword like this:\n:label_name:\n/* loop forever */\ngoto(label_name)\n\n\n95.1.21 Control flow\ngoto (addr) – branch execution\nwhile (cond)\nif (cond)\nif (cond) { body } else { body }\nbreak () – executes a trap instruction\n\n\n95.1.22 Comments\nSupported syntax for comments are:\n/* multiline comment */'\n// single line comment\n# single line comment", "crumbs": [ "Command Line Tools", - "94  Syntax of the language" + "95  Syntax of the language" ] }, { "objectID": "src/tools/rz-hash/intro.html", "href": "src/tools/rz-hash/intro.html", - "title": "95  Rz-hash", + "title": "96  Rz-hash", "section": "", - "text": "95.1 Hashing by blocks\nThe rz-hash tool can be used to compute checksums of files, disk devices or strings. By block or entirely using many different hash algorithms.\nThis tool is also capable of doing some encoding/decoding operations like base64 and xor encoding.\nThis is an example usage:\nNote that rz-hash also permits to read from files in a stream, so you don’t need 4GB of ram to compute the hash of a 4GB file.\nWhen doing forensics, it is useful to compute partial checksums. The reason for that is because you may want to split a huge file into small portions that are easier to identify by contents or regions in the disk.\nThis will spot the same hash for blocks containing the same contents. For example, if is filled with zeros.\nIt can also be used to find which blocks have changed between more than one sample dump.\nThis can be useful when analyzing ram dumps from a virtual machine for example. Use this command for this:", + "text": "96.1 Hashing by blocks\nThe rz-hash tool can be used to compute checksums of files, disk devices or strings. By block or entirely using many different hash algorithms.\nThis tool is also capable of doing some encoding/decoding operations like base64 and xor encoding.\nThis is an example usage:\nNote that rz-hash also permits to read from files in a stream, so you don’t need 4GB of ram to compute the hash of a 4GB file.\nWhen doing forensics, it is useful to compute partial checksums. The reason for that is because you may want to split a huge file into small portions that are easier to identify by contents or regions in the disk.\nThis will spot the same hash for blocks containing the same contents. For example, if is filled with zeros.\nIt can also be used to find which blocks have changed between more than one sample dump.\nThis can be useful when analyzing ram dumps from a virtual machine for example. Use this command for this:", "crumbs": [ "Command Line Tools", - "95  Rz-hash" + "96  Rz-hash" ] }, { "objectID": "src/tools/rz-hash/intro.html#hashing-by-blocks", "href": "src/tools/rz-hash/intro.html#hashing-by-blocks", - "title": "95  Rz-hash", + "title": "96  Rz-hash", "section": "", "text": "$ rz-hash -b 1M -B -a sha256 /usr/bin/ls\n/usr/bin/ls: 0x00000000-0x00000001 sha256: 620bfdaa346b088fb49998d92f19a7eaf6bfc2fb0aee015753966da1028cb731\n/usr/bin/ls: 0x00000001-0x00000002 sha256: a9f51566bd6705f7ea6ad54bb9deb449f795582d6529a0e22207b8981233ec58\n/usr/bin/ls: 0x00000002-0x00000003 sha256: 72dfcfb0c470ac255cde83fb8fe38de8a128188e03ea5ba5b2a93adbea1062fa\n/usr/bin/ls: 0x00000003-0x00000004 sha256: f67ab10ad4e4c53121b6a5fe4da9c10ddee905b978d3788d2723d7bfacbe28a9\n/usr/bin/ls: 0x00000004-0x00000005 sha256: dbc1b4c900ffe48d575b5da5c638040125f65db0fe3e24494b76ea986457d986\n/usr/bin/ls: 0x00000005-0x00000006 sha256: 4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a\n/usr/bin/ls: 0x00000006-0x00000007 sha256: 4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a\n/usr/bin/ls: 0x00000007-0x00000008 sha256: 6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d\n/usr/bin/ls: 0x00000008-0x00000009 sha256: 6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d\n...", "crumbs": [ "Command Line Tools", - "95  Rz-hash" + "96  Rz-hash" ] }, { "objectID": "src/tools/rz-hash/intro.html#hashing-with-rz-bin", "href": "src/tools/rz-hash/intro.html#hashing-with-rz-bin", - "title": "95  Rz-hash", - "section": "95.2 Hashing with rz-bin", - "text": "95.2 Hashing with rz-bin\nThe rz-bin tool parses the binary headers of the files, but it also have the ability to use the rhash plugins to compute checksum of sections in the binary.\n$ rz-bin -K md5 -S /usr/bin/ls\n[Sections]\npaddr size vaddr vsize align perm name type flags md5 \n------------------------------------------------------------------------------------------------------------------------------\n0x00000000 0x0 ---------- 0x0 0x0 ---- NULL \n0x00000318 0x1c 0x00000318 0x1c 0x0 -r-- .interp PROGBITS alloc 91476dafa5ef669483350538fa6ec4cb\n0x00000338 0x50 0x00000338 0x50 0x0 -r-- .note.gnu.property NOTE alloc b020406d0153b9a8b093dc5320cf1858\n0x00000388 0x20 0x00000388 0x20 0x0 -r-- .note.ABI-tag NOTE alloc 3ac31b2ebb8a59ed3542fd7de044fbeb\n0x000003a8 0x98 0x000003a8 0x98 0x0 -r-- .gnu.hash GNU_HASH alloc 66294f432dce133a6929d846de86169d\n0x00000440 0xaf8 0x00000440 0xaf8 0x0 -r-- .dynsym DYNSYM alloc 774725bcfcbbb51079e3fd2973c3aa41\n0x00000f38 0x564 0x00000f38 0x564 0x0 -r-- .dynstr STRTAB alloc 1fe7093dac1a162ed80703082430bc66\n0x0000149c 0xea 0x0000149c 0xea 0x0 -r-- .gnu.version VERSYM alloc b28fd251f91eb3d1be5a1d68a83499b0\n0x00001588 0xe0 0x00001588 0xe0 0x0 -r-- .gnu.version_r VERNEED alloc 443b0d1c61039ec732b43fea288b2e65\n0x00001668 0x150 0x00001668 0x150 0x0 -r-- .rela.dyn RELA alloc dbbe4ca304f452516463a3d53b66410d\n0x000017b8 0x948 0x000017b8 0x948 0x0 -r-- .rela.plt RELA alloc,info 0b50c15bd0eea13bd064b74d0854f55a\n0x00002100 0x50 0x00002100 0x50 0x0 -r-- .relr.dyn NUM alloc 888d536429b8c32d615ee09e6f48bc8e\n0x00003000 0x1b 0x00003000 0x1b 0x0 -r-x .init PROGBITS alloc,execute 34780ae97b075b73ee8ed3c08929bb2d\n0x00003020 0x640 0x00003020 0x640 0x0 -r-x .plt PROGBITS alloc,execute 6fb9ff6fe33cf9724ff1881cae5ddc3a\n0x00003660 0x40 0x00003660 0x40 0x0 -r-x .plt.got PROGBITS alloc,execute c3f69157c5b164dde89f4d93d01a2fbb\n0x000036a0 0x630 0x000036a0 0x630 0x0 -r-x .plt.sec PROGBITS alloc,execute 100ad3792d4e9afca167c23151a4b81d\n0x00003cd0 0x14972 0x00003cd0 0x14972 0x0 -r-x .text PROGBITS alloc,execute 90839f5851706a61bb3f87f0fba97be2\n0x00018644 0xd 0x00018644 0xd 0x0 -r-x .fini PROGBITS alloc,execute 7f954257b760b556cf4c5678b9b1ba6c\n0x00019000 0x5453 0x00019000 0x5453 0x0 -r-- .rodata PROGBITS alloc a6452d25e0a10ac8e59df34eba3237fc\n0x0001e454 0x9b4 0x0001e454 0x9b4 0x0 -r-- .eh_frame_hdr PROGBITS alloc ad1d1656aae20f61478eafef5735ad02\n0x0001ee08 0x3348 0x0001ee08 0x3348 0x0 -r-- .eh_frame PROGBITS alloc abb13e58f45411038e69c9ea963cf132\n0x00022f50 0x8 0x00023f50 0x8 0x0 -rw- .init_array INIT_ARRAY write,alloc b7e2f760e1a646fcbdbc90e96e559b98\n0x00022f58 0x8 0x00023f58 0x8 0x0 -rw- .fini_array FINI_ARRAY write,alloc c8fb88b08b2f528a3e4be0ed611f5ceb\n0x00022f60 0xaf8 0x00023f60 0xaf8 0x0 -rw- .data.rel.ro PROGBITS write,alloc c269cce7d0d0d50ffefd4cc280e04dda\n0x00023a58 0x220 0x00024a58 0x220 0x0 -rw- .dynamic DYNAMIC write,alloc 361d08a3c3a340966033f22e686839c2\n0x00023c78 0x370 0x00024c78 0x370 0x0 -rw- .got PROGBITS write,alloc 7731c689f4ca5fa4d6327707418424ce\n0x00024000 0x280 0x00025000 0x280 0x0 -rw- .data PROGBITS write,alloc 408649c72414b451e99cabc3b72cc401\n0x00024280 0x0 0x00025280 0x12d8 0x0 -rw- .bss NOBITS write,alloc\n0x00024280 0x105 ---------- 0x105 0x0 ---- .shstrtab STRTAB 87b94c07525325673cb9303007685933", + "title": "96  Rz-hash", + "section": "96.2 Hashing with rz-bin", + "text": "96.2 Hashing with rz-bin\nThe rz-bin tool parses the binary headers of the files, but it also have the ability to use the rhash plugins to compute checksum of sections in the binary.\n$ rz-bin -K md5 -S /usr/bin/ls\n[Sections]\npaddr size vaddr vsize align perm name type flags md5 \n------------------------------------------------------------------------------------------------------------------------------\n0x00000000 0x0 ---------- 0x0 0x0 ---- NULL \n0x00000318 0x1c 0x00000318 0x1c 0x0 -r-- .interp PROGBITS alloc 91476dafa5ef669483350538fa6ec4cb\n0x00000338 0x50 0x00000338 0x50 0x0 -r-- .note.gnu.property NOTE alloc b020406d0153b9a8b093dc5320cf1858\n0x00000388 0x20 0x00000388 0x20 0x0 -r-- .note.ABI-tag NOTE alloc 3ac31b2ebb8a59ed3542fd7de044fbeb\n0x000003a8 0x98 0x000003a8 0x98 0x0 -r-- .gnu.hash GNU_HASH alloc 66294f432dce133a6929d846de86169d\n0x00000440 0xaf8 0x00000440 0xaf8 0x0 -r-- .dynsym DYNSYM alloc 774725bcfcbbb51079e3fd2973c3aa41\n0x00000f38 0x564 0x00000f38 0x564 0x0 -r-- .dynstr STRTAB alloc 1fe7093dac1a162ed80703082430bc66\n0x0000149c 0xea 0x0000149c 0xea 0x0 -r-- .gnu.version VERSYM alloc b28fd251f91eb3d1be5a1d68a83499b0\n0x00001588 0xe0 0x00001588 0xe0 0x0 -r-- .gnu.version_r VERNEED alloc 443b0d1c61039ec732b43fea288b2e65\n0x00001668 0x150 0x00001668 0x150 0x0 -r-- .rela.dyn RELA alloc dbbe4ca304f452516463a3d53b66410d\n0x000017b8 0x948 0x000017b8 0x948 0x0 -r-- .rela.plt RELA alloc,info 0b50c15bd0eea13bd064b74d0854f55a\n0x00002100 0x50 0x00002100 0x50 0x0 -r-- .relr.dyn NUM alloc 888d536429b8c32d615ee09e6f48bc8e\n0x00003000 0x1b 0x00003000 0x1b 0x0 -r-x .init PROGBITS alloc,execute 34780ae97b075b73ee8ed3c08929bb2d\n0x00003020 0x640 0x00003020 0x640 0x0 -r-x .plt PROGBITS alloc,execute 6fb9ff6fe33cf9724ff1881cae5ddc3a\n0x00003660 0x40 0x00003660 0x40 0x0 -r-x .plt.got PROGBITS alloc,execute c3f69157c5b164dde89f4d93d01a2fbb\n0x000036a0 0x630 0x000036a0 0x630 0x0 -r-x .plt.sec PROGBITS alloc,execute 100ad3792d4e9afca167c23151a4b81d\n0x00003cd0 0x14972 0x00003cd0 0x14972 0x0 -r-x .text PROGBITS alloc,execute 90839f5851706a61bb3f87f0fba97be2\n0x00018644 0xd 0x00018644 0xd 0x0 -r-x .fini PROGBITS alloc,execute 7f954257b760b556cf4c5678b9b1ba6c\n0x00019000 0x5453 0x00019000 0x5453 0x0 -r-- .rodata PROGBITS alloc a6452d25e0a10ac8e59df34eba3237fc\n0x0001e454 0x9b4 0x0001e454 0x9b4 0x0 -r-- .eh_frame_hdr PROGBITS alloc ad1d1656aae20f61478eafef5735ad02\n0x0001ee08 0x3348 0x0001ee08 0x3348 0x0 -r-- .eh_frame PROGBITS alloc abb13e58f45411038e69c9ea963cf132\n0x00022f50 0x8 0x00023f50 0x8 0x0 -rw- .init_array INIT_ARRAY write,alloc b7e2f760e1a646fcbdbc90e96e559b98\n0x00022f58 0x8 0x00023f58 0x8 0x0 -rw- .fini_array FINI_ARRAY write,alloc c8fb88b08b2f528a3e4be0ed611f5ceb\n0x00022f60 0xaf8 0x00023f60 0xaf8 0x0 -rw- .data.rel.ro PROGBITS write,alloc c269cce7d0d0d50ffefd4cc280e04dda\n0x00023a58 0x220 0x00024a58 0x220 0x0 -rw- .dynamic DYNAMIC write,alloc 361d08a3c3a340966033f22e686839c2\n0x00023c78 0x370 0x00024c78 0x370 0x0 -rw- .got PROGBITS write,alloc 7731c689f4ca5fa4d6327707418424ce\n0x00024000 0x280 0x00025000 0x280 0x0 -rw- .data PROGBITS write,alloc 408649c72414b451e99cabc3b72cc401\n0x00024280 0x0 0x00025280 0x12d8 0x0 -rw- .bss NOBITS write,alloc\n0x00024280 0x105 ---------- 0x105 0x0 ---- .shstrtab STRTAB 87b94c07525325673cb9303007685933", "crumbs": [ "Command Line Tools", - "95  Rz-hash" + "96  Rz-hash" ] }, { "objectID": "src/tools/rz-hash/intro.html#obtaining-hashes-within-rizin-session", "href": "src/tools/rz-hash/intro.html#obtaining-hashes-within-rizin-session", - "title": "95  Rz-hash", - "section": "95.3 Obtaining hashes within rizin session", - "text": "95.3 Obtaining hashes within rizin session\nTo calculate a checksum of current block when running Rizin, use the ph command. Pass an algorithm name to it as a parameter. An example session:\n$ rizin /usr/bin/ls\n[0x00005880]> bf entry0\n[0x00005880]> ph md5\n6334c2ae05c2421c687f516772b817da\nYou can use all hashing algorithms supported by rz-hash:\n[0x00000000]> phl\nalgorithm license author\nmd2 LGPL3 swedenspy\nmd4 Apache 2.0 OpenSSL Team\nmd5 Apache 2.0 OpenSSL Team\nsha1 Apache 2.0 OpenSSL Team\nsha256 Apache 2.0 OpenSSL Team\nsha384 Apache 2.0 OpenSSL Team\nsha512 Apache 2.0 OpenSSL Team\nsm3 Apache 2.0 OpenSSL Team\nblake3 CC0 Samuel Neves,Jack O'Connor\nfletcher8 LGPL3 deroad\nfletcher16 LGPL3 deroad\nfletcher32 LGPL3 deroad\nfletcher64 LGPL3 deroad\nadler32 LGPL3 deroad\ncrc8smbus LGPL3 deroad\ncrc8cdma2000 LGPL3 deroad\ncrc8darc LGPL3 deroad\ncrc8dvbs2 LGPL3 deroad\ncrc8ebu LGPL3 deroad\ncrc8icode LGPL3 deroad\ncrc8itu LGPL3 deroad\ncrc8maxim LGPL3 deroad\ncrc8rohc LGPL3 deroad\ncrc8wcdma LGPL3 deroad\ncrc15can LGPL3 deroad\ncrc16 LGPL3 deroad\ncrc16citt LGPL3 deroad\ncrc16usb LGPL3 deroad\ncrc16hdlc LGPL3 deroad\ncrc16augccitt LGPL3 deroad\ncrc16buypass LGPL3 deroad\ncrc16cdma2000 LGPL3 deroad\ncrc16dds110 LGPL3 deroad\ncrc16dectr LGPL3 deroad\ncrc16dectx LGPL3 deroad\ncrc16dnp LGPL3 deroad\ncrc16en13757 LGPL3 deroad\ncrc16genibus LGPL3 deroad\ncrc16maxim LGPL3 deroad\ncrc16mcrf4xx LGPL3 deroad\ncrc16riello LGPL3 deroad\ncrc16t10dif LGPL3 deroad\ncrc16teledisk LGPL3 deroad\ncrc16tms37157 LGPL3 deroad\ncrca LGPL3 deroad\ncrc16kermit LGPL3 deroad\ncrc16modbus LGPL3 deroad\ncrc16x25 LGPL3 deroad\ncrc16xmodem LGPL3 deroad\ncrc24 LGPL3 deroad\ncrc32 LGPL3 deroad\ncrc32ecma267 LGPL3 deroad\ncrc32c LGPL3 deroad\ncrc32bzip2 LGPL3 deroad\ncrc32d LGPL3 deroad\ncrc32mpeg2 LGPL3 deroad\ncrc32posix LGPL3 deroad\ncrc32q LGPL3 deroad\ncrc32jamcrc LGPL3 deroad\ncrc32xfer LGPL3 deroad\ncrc64 LGPL3 deroad\ncrc64ecma182 LGPL3 deroad\ncrc64we LGPL3 deroad\ncrc64xz LGPL3 deroad\ncrc64iso LGPL3 deroad\nxor8 LGPL3 deroad\nxor16 LGPL3 deroad\nxxhash32 LGPL3 deroad\nssdeep LGPL3 deroad\nparity LGPL3 deroad\nentropy LGPL3 deroad\nentropy_fract LGPL3 deroad\nThe ph command accepts an optional numeric argument to specify length of byte range to be hashed, instead of default block size. For example:\n[0x08049A80]> ph md5 32\n9b9012b00ef7a94b5824105b7aaad83b\n[0x08049A80]> ph md5 64\na71b087d8166c99869c9781e2edcf183\n[0x08049A80]> ph md5 1024\na933cc94cd705f09a41ecc80c0041def", + "title": "96  Rz-hash", + "section": "96.3 Obtaining hashes within rizin session", + "text": "96.3 Obtaining hashes within rizin session\nTo calculate a checksum of current block when running Rizin, use the ph command. Pass an algorithm name to it as a parameter. An example session:\n$ rizin /usr/bin/ls\n[0x00005880]> bf entry0\n[0x00005880]> ph md5\n6334c2ae05c2421c687f516772b817da\nYou can use all hashing algorithms supported by rz-hash:\n[0x00000000]> phl\nalgorithm license author\nmd2 LGPL3 swedenspy\nmd4 Apache 2.0 OpenSSL Team\nmd5 Apache 2.0 OpenSSL Team\nsha1 Apache 2.0 OpenSSL Team\nsha256 Apache 2.0 OpenSSL Team\nsha384 Apache 2.0 OpenSSL Team\nsha512 Apache 2.0 OpenSSL Team\nsm3 Apache 2.0 OpenSSL Team\nblake3 CC0 Samuel Neves,Jack O'Connor\nfletcher8 LGPL3 deroad\nfletcher16 LGPL3 deroad\nfletcher32 LGPL3 deroad\nfletcher64 LGPL3 deroad\nadler32 LGPL3 deroad\ncrc8smbus LGPL3 deroad\ncrc8cdma2000 LGPL3 deroad\ncrc8darc LGPL3 deroad\ncrc8dvbs2 LGPL3 deroad\ncrc8ebu LGPL3 deroad\ncrc8icode LGPL3 deroad\ncrc8itu LGPL3 deroad\ncrc8maxim LGPL3 deroad\ncrc8rohc LGPL3 deroad\ncrc8wcdma LGPL3 deroad\ncrc15can LGPL3 deroad\ncrc16 LGPL3 deroad\ncrc16citt LGPL3 deroad\ncrc16usb LGPL3 deroad\ncrc16hdlc LGPL3 deroad\ncrc16augccitt LGPL3 deroad\ncrc16buypass LGPL3 deroad\ncrc16cdma2000 LGPL3 deroad\ncrc16dds110 LGPL3 deroad\ncrc16dectr LGPL3 deroad\ncrc16dectx LGPL3 deroad\ncrc16dnp LGPL3 deroad\ncrc16en13757 LGPL3 deroad\ncrc16genibus LGPL3 deroad\ncrc16maxim LGPL3 deroad\ncrc16mcrf4xx LGPL3 deroad\ncrc16riello LGPL3 deroad\ncrc16t10dif LGPL3 deroad\ncrc16teledisk LGPL3 deroad\ncrc16tms37157 LGPL3 deroad\ncrca LGPL3 deroad\ncrc16kermit LGPL3 deroad\ncrc16modbus LGPL3 deroad\ncrc16x25 LGPL3 deroad\ncrc16xmodem LGPL3 deroad\ncrc24 LGPL3 deroad\ncrc32 LGPL3 deroad\ncrc32ecma267 LGPL3 deroad\ncrc32c LGPL3 deroad\ncrc32bzip2 LGPL3 deroad\ncrc32d LGPL3 deroad\ncrc32mpeg2 LGPL3 deroad\ncrc32posix LGPL3 deroad\ncrc32q LGPL3 deroad\ncrc32jamcrc LGPL3 deroad\ncrc32xfer LGPL3 deroad\ncrc64 LGPL3 deroad\ncrc64ecma182 LGPL3 deroad\ncrc64we LGPL3 deroad\ncrc64xz LGPL3 deroad\ncrc64iso LGPL3 deroad\nxor8 LGPL3 deroad\nxor16 LGPL3 deroad\nxxhash32 LGPL3 deroad\nssdeep LGPL3 deroad\nparity LGPL3 deroad\nentropy LGPL3 deroad\nentropy_fract LGPL3 deroad\nThe ph command accepts an optional numeric argument to specify length of byte range to be hashed, instead of default block size. For example:\n[0x08049A80]> ph md5 32\n9b9012b00ef7a94b5824105b7aaad83b\n[0x08049A80]> ph md5 64\na71b087d8166c99869c9781e2edcf183\n[0x08049A80]> ph md5 1024\na933cc94cd705f09a41ecc80c0041def", "crumbs": [ "Command Line Tools", - "95  Rz-hash" + "96  Rz-hash" ] }, { "objectID": "src/tools/rz-hash/rz-hash_tool.html", "href": "src/tools/rz-hash/rz-hash_tool.html", - "title": "96  Examples", + "title": "97  Examples", "section": "", "text": "The rz-hash tool can be used to calculate checksums and has functions of byte streams, files, text strings.\n$ rz-hash -h\nUsage: rz-hash [-vhBkjLq] [-b S] [-a A] [-c H] [-E A] [-D A] [-s S] [-x S] [-f O] [-t O] [files|-] ...\n -v Show version information\n -h Show this help\n - Input read from stdin instead from a file\n -a algo Hash algorithm to use and you can specify multiple ones by\n Appending a comma (example: sha1,md4,md5,sha256)\n -B Output the calculated value for each block\n -b size Set the block size\n -c value Compare calculated value with a given one (hexadecimal)\n -e endian Set the endianness (default: 'big' accepted: 'big' or 'little')\n -D algo Decrypt the given input; use -S to set key and -I to set IV (if needed)\n -E algo Encrypt the given input; use -S to set key and -I to set IV (if needed)\n -f from Start the calculation at given offset\n -t to Stop the calculation at given offset\n -I iv Set the initialization vector (IV)\n -i times Repeat the calculation N times\n -j Output the result as a JSON structure\n -k Output the calculated value using openssh's randomkey algorithm\n -L List all algorithms\n -q Set quiet mode (use -qq to get only the calculated value)\n -S seed Set the seed for -a, use '^' to append it before the input, use '@'\n Prefix to load it from a file and '-' from read it\n -K key Set the hmac key for -a and the key for -E/-D, use '@' prefix to\n Load it from a file and '-' from read it\n From stdin (you can combine them)\n -s string Input read from a zero-terminated string instead from a file\n -x hex Input read from a hexadecimal value instead from a file\n \n All the input (besides -s/-x/-c) can be hexadecimal or strings\n If 's:' prefix is specified\nTo obtain an MD5 hash value of a text string, use the -s option:\n$ rz-hash -q -a md5 -s 'hello world'\nstring: md5: 5eb63bbbe01eeed093cb22bb8f5acdc3\nIt is possible to calculate hash values for contents of files. But do not attempt to do it for very large files because rz-hash buffers the whole input in memory before computing the hash.\nTo apply all algorithms known to rz-hash, use all as an algorithm name:\n$ rz-hash -a all /usr/bin/ls\n/usr/bin/ls: 0x00000000-0x00024ac8 md2: 9a2a86a52e9cb44b2e06a58a00fee15e\n/usr/bin/ls: 0x00000000-0x00024ac8 md4: 725fc3498847e96d031ce4d1f4872b28\n/usr/bin/ls: 0x00000000-0x00024ac8 md5: bcf16aef7487e6ea478a168c180c07fa\n/usr/bin/ls: 0x00000000-0x00024ac8 sha1: ccb226a119fe301b2ad2dc8a7013faf6f6296ea1\n/usr/bin/ls: 0x00000000-0x00024ac8 sha256: 1ba437f3522d9e416f66425fdb816dfbaf32b4140d2092f2b8922b2825e4065a\n/usr/bin/ls: 0x00000000-0x00024ac8 sha384: fd51260b6db6940f37a3177b033e1a7e9c1cedd3ee5c9c45e3dfdac135a65edf991313da7083551f091ef553e2f4fe29\n/usr/bin/ls: 0x00000000-0x00024ac8 sha512: de26d5385088825cce3fcb87645ddf2148e4c71013ff98170ccd106795d6cf4669e1b71053593472667ff64f17a0190ab3d99430d784a0489c7bc6344d5605db\n/usr/bin/ls: 0x00000000-0x00024ac8 sm3: 9410230b34c9ab0c527c21cbdb9f953cc747479c89d019a4f6ae4c7cffd40bb0\n/usr/bin/ls: 0x00000000-0x00024ac8 blake3: 5805f287d8c0107ffdc7960b6112b586940d9767e888023048543daefa4cf6e5\n/usr/bin/ls: 0x00000000-0x00024ac8 fletcher8: dd\n/usr/bin/ls: 0x00000000-0x00024ac8 fletcher16: ddf3\n/usr/bin/ls: 0x00000000-0x00024ac8 fletcher32: dd003c1a\n/usr/bin/ls: 0x00000000-0x00024ac8 fletcher64: 5952f47d393a5468\n/usr/bin/ls: 0x00000000-0x00024ac8 adler32: 86e2c3a1\n/usr/bin/ls: 0x00000000-0x00024ac8 crc8smbus: 15\n/usr/bin/ls: 0x00000000-0x00024ac8 crc8cdma2000: d9\n/usr/bin/ls: 0x00000000-0x00024ac8 crc8darc: 3b\n/usr/bin/ls: 0x00000000-0x00024ac8 crc8dvbs2: 3d\n/usr/bin/ls: 0x00000000-0x00024ac8 crc8ebu: 67\n/usr/bin/ls: 0x00000000-0x00024ac8 crc8icode: 67\n/usr/bin/ls: 0x00000000-0x00024ac8 crc8itu: 40\n/usr/bin/ls: 0x00000000-0x00024ac8 crc8maxim: b3\n/usr/bin/ls: 0x00000000-0x00024ac8 crc8rohc: ad\n/usr/bin/ls: 0x00000000-0x00024ac8 crc8wcdma: ab\n/usr/bin/ls: 0x00000000-0x00024ac8 crc15can: 7126\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16: f310\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16citt: be97\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16usb: 9f67\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16hdlc: 282a\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16augccitt: 5c10\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16buypass: fc1c\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16cdma2000: d203\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16dds110: 98aa\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16dectr: 0485\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16dectx: 0484\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16dnp: d2fd\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16en13757: f12e\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16genibus: 4168\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16maxim: 0cef\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16mcrf4xx: d7d5\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16riello: ecaa\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16t10dif: faeb\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16teledisk: bee3\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16tms37157: 60a7\n/usr/bin/ls: 0x00000000-0x00024ac8 crca: e518\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16kermit: 0dcc\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16modbus: 6098\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16x25: 282a\n/usr/bin/ls: 0x00000000-0x00024ac8 crc16xmodem: 26cc\n/usr/bin/ls: 0x00000000-0x00024ac8 crc24: 0078edb6\n/usr/bin/ls: 0x00000000-0x00024ac8 crc32: ea7111a0\n/usr/bin/ls: 0x00000000-0x00024ac8 crc32ecma267: d7f2cb8a\n/usr/bin/ls: 0x00000000-0x00024ac8 crc32c: bb2af410\n/usr/bin/ls: 0x00000000-0x00024ac8 crc32bzip2: b307ddba\n/usr/bin/ls: 0x00000000-0x00024ac8 crc32d: 5de137a9\n/usr/bin/ls: 0x00000000-0x00024ac8 crc32mpeg2: 4cf82245\n/usr/bin/ls: 0x00000000-0x00024ac8 crc32posix: 35f6bff2\n/usr/bin/ls: 0x00000000-0x00024ac8 crc32q: 54013d42\n/usr/bin/ls: 0x00000000-0x00024ac8 crc32jamcrc: 158eee5f\n/usr/bin/ls: 0x00000000-0x00024ac8 crc32xfer: 7d03019b\n/usr/bin/ls: 0x00000000-0x00024ac8 crc64: 60f233ef3032deac\n/usr/bin/ls: 0x00000000-0x00024ac8 crc64ecma182: 60f233ef3032deac\n/usr/bin/ls: 0x00000000-0x00024ac8 crc64we: c52bf0d6179e06ef\n/usr/bin/ls: 0x00000000-0x00024ac8 crc64xz: eab2da06f0ff2682\n/usr/bin/ls: 0x00000000-0x00024ac8 crc64iso: 8734628b8dc355f3\n/usr/bin/ls: 0x00000000-0x00024ac8 xor8: fd\n/usr/bin/ls: 0x00000000-0x00024ac8 xor16: 67ec\n/usr/bin/ls: 0x00000000-0x00024ac8 xxhash32: 8a1da333\n/usr/bin/ls: 0x00000000-0x00024ac8 ssdeep: 3072:HANnWPSHOTx1XPglbUXVoaJzbuWXod7QHwOP1hKYfrMJM:HABAIi162VjJzCpJQHwWhHr0\n/usr/bin/ls: 0x00000000-0x00024ac8 parity: 01\n/usr/bin/ls: 0x00000000-0x00024ac8 entropy: 5.95354820\n/usr/bin/ls: 0x00000000-0x00024ac8 entropy_fract: 0.74419352", "crumbs": [ "Command Line Tools", - "96  Examples" + "97  Examples" ] }, { "objectID": "src/plugins/intro.html", "href": "src/plugins/intro.html", - "title": "97  Plugins", + "title": "98  Plugins", "section": "", - "text": "97.1 Types of plugins\nRizin is implemented on top of a bunch of libraries, almost every of those libraries support plugins to extend the capabilities of the library or add support for different targets.\nThis section aims to explain what are the plugins, how to write them and use them", + "text": "98.1 Types of plugins\nRizin is implemented on top of a bunch of libraries, almost every of those libraries support plugins to extend the capabilities of the library or add support for different targets.\nThis section aims to explain what are the plugins, how to write them and use them", "crumbs": [ "Plugins", - "97  Plugins" + "98  Plugins" ] }, { "objectID": "src/plugins/intro.html#types-of-plugins", "href": "src/plugins/intro.html#types-of-plugins", - "title": "97  Plugins", + "title": "98  Plugins", "section": "", "text": "$ ls librz/*/p | grep : | awk -F / '{ print $2 }'\nanalysis # analysis plugins\nasm # assembler/disassembler plugins\nbin # binary format parsing plugins\nbp # breakpoint plugins\ncore # core plugins (implement new commands)\ncrypto # encrypt/decrypt/hash/...\ndebug # debugger backends\negg # shellcode encoders, etc\nio # io plugins\nlang # embedded scripting languages\nparse # disassembler parsing plugins\nreg # arch register logic", "crumbs": [ "Plugins", - "97  Plugins" + "98  Plugins" ] }, { "objectID": "src/plugins/intro.html#listing-plugins", "href": "src/plugins/intro.html#listing-plugins", - "title": "97  Plugins", - "section": "97.2 Listing plugins", - "text": "97.2 Listing plugins\nSome Rizin tools have the -L flag to list all the plugins associated to the functionality.\nrz-asm -L # list asm plugins\nrizin -L # list io plugins\nrz-bin -L # list bin plugins\nrz-hash -L # list hash/crypto/encoding plugins\nThere are more plugins in Rizin ecosystem, we can list them from inside Rizin, and this is done by using the L suffix.\nThose are some of the commands:\nL # list core plugins\niL # list bin plugins\ndL # list debug plugins\nph # print support hash algorithms\nwoD?/woE? # print support crypto/encoding algorithms\nYou can use the ? as value to get the possible values in the associated eval vars.\ne asm.arch=? # list assembler/disassembler plugins\ne analysis.arch=? # list analysis plugins", + "title": "98  Plugins", + "section": "98.2 Listing plugins", + "text": "98.2 Listing plugins\nSome Rizin tools have the -L flag to list all the plugins associated to the functionality.\nrz-asm -L # list asm plugins\nrizin -L # list io plugins\nrz-bin -L # list bin plugins\nrz-hash -L # list hash/crypto/encoding plugins\nThere are more plugins in Rizin ecosystem, we can list them from inside Rizin, and this is done by using the L suffix.\nThose are some of the commands:\nL # list core plugins\niL # list bin plugins\ndL # list debug plugins\nph # print support hash algorithms\nwoD?/woE? # print support crypto/encoding algorithms\nYou can use the ? as value to get the possible values in the associated eval vars.\ne asm.arch=? # list assembler/disassembler plugins\ne analysis.arch=? # list analysis plugins", "crumbs": [ "Plugins", - "97  Plugins" + "98  Plugins" ] }, { "objectID": "src/plugins/intro.html#notes", "href": "src/plugins/intro.html#notes", - "title": "97  Plugins", - "section": "97.3 Notes", - "text": "97.3 Notes\nNote there are some inconsistencies that most likely will be fixed in the future Rizin versions.", + "title": "98  Plugins", + "section": "98.3 Notes", + "text": "98.3 Notes\nNote there are some inconsistencies that most likely will be fixed in the future Rizin versions.", "crumbs": [ "Plugins", - "97  Plugins" + "98  Plugins" ] }, { "objectID": "src/plugins/ioplugins.html", "href": "src/plugins/ioplugins.html", - "title": "98  IO plugins", + "title": "99  IO plugins", "section": "", "text": "All access to files, network, debugger and all input/output in general is wrapped by an IO abstraction layer that allows Rizin to treat all data as if it were just a file.\nIO plugins are the ones used to wrap the open, read, write and ‘system’ on virtual file systems. You can make Rizin understand anything as a plain file. E.g. a socket connection, a remote rizin session, a file, a process, a device, a gdb session.\nSo, when rizin reads a block of bytes, it is the task of an IO plugin to get these bytes from any place and put them into internal buffer. An IO plugin is chosen by a file’s URI to be opened. Some examples:\n\nDebugging URIs\n\n$ rizin dbg:///bin/ls<br />\n$ rizin pid://1927\n\nRemote sessions\n\n$ rizin rap://:1234<br />\n$ rizin rap://<host>:1234//bin/ls\n\nVirtual buffers\n\n$ rizin malloc://512<br />\nshortcut for\n$ rizin =\nYou can get a list of the rizin IO plugins by typing rizin -L:\n$ rizin -L\nrw_ ar Open ar/lib files [ar|lib]://[file//path] (LGPL3)\nrw_ bfdbg BrainFuck Debugger (bfdbg://path/to/file) (LGPL3)\nrwd bochs Attach to a BOCHS debugger (LGPL3)\nr_d debug Native debugger (dbg:///bin/ls dbg://1388 pidof:// waitfor://) (LGPL3) v0.2.0 pancake\nrw_ default open local files using def_mmap:// (LGPL3)\nrwd gdb Attach to gdbserver, 'qemu -s', gdb://localhost:1234 (LGPL3)\nrw_ gprobe open gprobe connection using gprobe:// (LGPL3)\nrw_ gzip read/write gzipped files (LGPL3)\nrw_ http http get (http://rada.re/) (LGPL3)\nrw_ ihex Intel HEX file (ihex://eeproms.hex) (LGPL)\nr__ mach mach debug io (unsupported in this platform) (LGPL)\nrw_ malloc memory allocation (malloc://1024 hex://cd8090) (LGPL3)\nrw_ mmap open file using mmap:// (LGPL3)\nrw_ null null-plugin (null://23) (LGPL3)\nrw_ procpid /proc/pid/mem io (LGPL3)\nrwd ptrace ptrace and /proc/pid/mem (if available) io (LGPL3)\nrwd qnx Attach to QNX pdebug instance, qnx://host:1234 (LGPL3)\nrw_ rzk kernel access API io (rzk://) (LGPL3)\nrw_ rz-pipe rz-pipe io plugin (MIT)\nrw_ rzweb rzweb io client (rzweb://cloud.rada.re/cmd/) (LGPL3)\nrw_ rap rizin network protocol (rap://:port rap://host:port/file) (LGPL3)\nrw_ rbuf RBuffer IO plugin: rbuf:// (LGPL)\nrw_ self read memory from myself using 'self://' (LGPL3)\nrw_ shm shared memory resources (shm://key) (LGPL3)\nrw_ sparse sparse buffer allocation (sparse://1024 sparse://) (LGPL3)\nrw_ tcp load files via TCP (listen or connect) (LGPL3)\nrwd windbg Attach to a KD debugger (windbg://socket) (LGPL3)\nrwd winedbg Wine-dbg io and debug.io plugin for rizin (MIT)\nrw_ zip Open zip files [apk|ipa|zip|zipall]://[file//path] (BSD)", "crumbs": [ "Plugins", - "98  IO plugins" + "99  IO plugins" ] }, { "objectID": "src/plugins/dev-asm.html", "href": "src/plugins/dev-asm.html", - "title": "99  Implementing a new disassembly plugin", + "title": "100  Implementing a new disassembly plugin", "section": "", - "text": "Rizin has modular architecture, thus adding support for a new architecture is very easy, if you are fluent in C. For various reasons it might be easier to implement it out of the tree. For this we will need to create single C file, called asm_mycpu.c and a meson file for it.\nThe key thing of RzAsm plugin is a structure\nRzAsmPlugin rz_asm_plugin_mycpu = {\n .name = \"mycpu\",\n .license = \"LGPL3\",\n .desc = \"MYCPU disassembly plugin\",\n .arch = \"mycpu\",\n .bits = 32,\n .endian = RZ_SYS_ENDIAN_LITTLE,\n .disassemble = &disassemble\n};\nwhere .disassemble is a pointer to disassembly function, which accepts the bytes buffer and length:\nstatic int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len)\nMeson\nproject('asm_mycpu', 'c')\n\nrz_asm_dep = dependency('rz_asm')\nplugins_dir = get_option('prefix') / rz_asm_dep.get_variable(pkgconfig: 'plugindir', cmake: 'rz_asm_PLUGINDIR')\nmessage('Plugins install directory: ' + plugins_dir)\n\nlibrary('asm_mycpu',\n ['asm_mycpu.c'],\n dependencies: [rz_asm_dep],\n install: true,\n install_dir: plugins_dir,\n)\nasm_mycpu.c\n/* rizin - LGPL - Copyright 2018 - user */\n\n#include <stdio.h>\n#include <string.h>\n#include <rz_types.h>\n#include <rz_lib.h>\n#include <rz_asm.h>\n\nstatic int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {\n struct op_cmd cmd = {\n .instr = \"\",\n .operands = \"\"\n };\n if (len < 2) return -1;\n int ret = decode_opcode (buf, len, &cmd);\n if (ret > 0) {\n snprintf (op->buf_asm, rz_asm_BUFSIZE, \"%s %s\",\n cmd.instr, cmd.operands);\n }\n return op->size = ret;\n}\n\nRzAsmPlugin rz_asm_plugin_mycpu = {\n .name = \"mycpu\",\n .license = \"LGPL3\",\n .desc = \"MYCPU disassembly plugin\",\n .arch = \"mycpu\",\n .bits = 32,\n .endian = RZ_SYS_ENDIAN_LITTLE,\n .disassemble = &disassemble\n};\n\n#ifndef RZ_PLUGIN_INCORE\nRZ_API RzLibStruct rizin_plugin = {\n .type = RZ_LIB_TYPE_ASM,\n .data = &rz_asm_plugin_mycpu,\n .version = RZ_VERSION\n};\n#endif\nAfter compiling rizin will list this plugin in the rz-asm output:\n$ rz-asm -L |grep myc\n_d__ _8_32 mycpu LGPL3 MYCPU disassembly plugin\n\n99.0.1 Moving plugin into the tree\nPushing a new architecture into the main branch of rizin requires to modify several files in order to make it fit into the way the rest of plugins are built.\nList of affected files:\n\nlibrz/asm/p/asm_mycpu.c That’s where most of our code will be, the key part is to declare a RzAsmPlugin containing a valid disassemble field, a function pointer to the actual disassembler function.\nlibrz/asm/meson.build The build is handled by meson, we have to add our plugin to the list of things to be compiled :\n\n@@ -49,6 +49,7 @@ asm_plugins_list = [\n 'x86_nz',\n 'xap',\n 'xcore_cs',\n+ 'mycpu',\n ]\n\n@@ -129,6 +130,7 @@ rz_asm_sources = [\n #'p/asm_x86_vm.c',\n 'p/asm_xap.c',\n 'p/asm_xcore_cs.c',\n+ 'p/asm_mycpu.c',\n #'arch/6502/6502dis.c',\n 'arch/amd29k/amd29k.c',\n #'arch/8051/8051_disas.c',\n+ 'arch/mycpu/mycpu_disas.c',\n 'arch/arm/armass.c',\n\n@@ -129,6 +130,7 @@ rz_asm_inc = [\n+ 'arch/mycpu',\n]\n\nlibrz/include/rz_asm.h Make Rizin aware of our plugin by defining our struct:\n\n@@ -265,6 +265,7 @@ extern RzAsmPlugin rz_asm_plugin_xcore_cs;\n extern RzAsmPlugin rz_asm_plugin_xtensa;\n extern RzAsmPlugin rz_asm_plugin_z80;\n extern RzAsmPlugin rz_asm_plugin_pyc;\n+extern RzAsmPlugin rz_asm_plugin_mycpu;\n\n #endif\nCheck out how the NIOS II CPU disassembly plugin was implemented by reading those commits:\nThe RzAsm plugin\nThe RzAnalysis plugin", + "text": "Rizin has modular architecture, thus adding support for a new architecture is very easy, if you are fluent in C. For various reasons it might be easier to implement it out of the tree. For this we will need to create single C file, called asm_mycpu.c and a meson file for it.\nThe key thing of RzAsm plugin is a structure\nRzAsmPlugin rz_asm_plugin_mycpu = {\n .name = \"mycpu\",\n .license = \"LGPL3\",\n .desc = \"MYCPU disassembly plugin\",\n .arch = \"mycpu\",\n .bits = 32,\n .endian = RZ_SYS_ENDIAN_LITTLE,\n .disassemble = &disassemble\n};\nwhere .disassemble is a pointer to disassembly function, which accepts the bytes buffer and length:\nstatic int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len)\nMeson\nproject('asm_mycpu', 'c')\n\nrz_asm_dep = dependency('rz_asm')\nplugins_dir = get_option('prefix') / rz_asm_dep.get_variable(pkgconfig: 'plugindir', cmake: 'rz_asm_PLUGINDIR')\nmessage('Plugins install directory: ' + plugins_dir)\n\nlibrary('asm_mycpu',\n ['asm_mycpu.c'],\n dependencies: [rz_asm_dep],\n install: true,\n install_dir: plugins_dir,\n)\nasm_mycpu.c\n/* rizin - LGPL - Copyright 2018 - user */\n\n#include <stdio.h>\n#include <string.h>\n#include <rz_types.h>\n#include <rz_lib.h>\n#include <rz_asm.h>\n\nstatic int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {\n struct op_cmd cmd = {\n .instr = \"\",\n .operands = \"\"\n };\n if (len < 2) return -1;\n int ret = decode_opcode (buf, len, &cmd);\n if (ret > 0) {\n snprintf (op->buf_asm, rz_asm_BUFSIZE, \"%s %s\",\n cmd.instr, cmd.operands);\n }\n return op->size = ret;\n}\n\nRzAsmPlugin rz_asm_plugin_mycpu = {\n .name = \"mycpu\",\n .license = \"LGPL3\",\n .desc = \"MYCPU disassembly plugin\",\n .arch = \"mycpu\",\n .bits = 32,\n .endian = RZ_SYS_ENDIAN_LITTLE,\n .disassemble = &disassemble\n};\n\n#ifndef RZ_PLUGIN_INCORE\nRZ_API RzLibStruct rizin_plugin = {\n .type = RZ_LIB_TYPE_ASM,\n .data = &rz_asm_plugin_mycpu,\n .version = RZ_VERSION\n};\n#endif\nAfter compiling rizin will list this plugin in the rz-asm output:\n$ rz-asm -L |grep myc\n_d__ _8_32 mycpu LGPL3 MYCPU disassembly plugin\n\n100.0.1 Moving plugin into the tree\nPushing a new architecture into the main branch of rizin requires to modify several files in order to make it fit into the way the rest of plugins are built.\nList of affected files:\n\nlibrz/asm/p/asm_mycpu.c That’s where most of our code will be, the key part is to declare a RzAsmPlugin containing a valid disassemble field, a function pointer to the actual disassembler function.\nlibrz/asm/meson.build The build is handled by meson, we have to add our plugin to the list of things to be compiled :\n\n@@ -49,6 +49,7 @@ asm_plugins_list = [\n 'x86_nz',\n 'xap',\n 'xcore_cs',\n+ 'mycpu',\n ]\n\n@@ -129,6 +130,7 @@ rz_asm_sources = [\n #'p/asm_x86_vm.c',\n 'p/asm_xap.c',\n 'p/asm_xcore_cs.c',\n+ 'p/asm_mycpu.c',\n #'arch/6502/6502dis.c',\n 'arch/amd29k/amd29k.c',\n #'arch/8051/8051_disas.c',\n+ 'arch/mycpu/mycpu_disas.c',\n 'arch/arm/armass.c',\n\n@@ -129,6 +130,7 @@ rz_asm_inc = [\n+ 'arch/mycpu',\n]\n\nlibrz/include/rz_asm.h Make Rizin aware of our plugin by defining our struct:\n\n@@ -265,6 +265,7 @@ extern RzAsmPlugin rz_asm_plugin_xcore_cs;\n extern RzAsmPlugin rz_asm_plugin_xtensa;\n extern RzAsmPlugin rz_asm_plugin_z80;\n extern RzAsmPlugin rz_asm_plugin_pyc;\n+extern RzAsmPlugin rz_asm_plugin_mycpu;\n\n #endif\nCheck out how the NIOS II CPU disassembly plugin was implemented by reading those commits:\nThe RzAsm plugin\nThe RzAnalysis plugin", "crumbs": [ "Plugins", - "99  Implementing a new disassembly plugin" + "100  Implementing a new disassembly plugin" ] }, { "objectID": "src/plugins/dev-analysis.html", "href": "src/plugins/dev-analysis.html", - "title": "100  Implementing a new analysis plugin", + "title": "101  Implementing a new analysis plugin", "section": "", "text": "After implementing disassembly plugin, you might have noticed that output is far from being good - no proper highlighting, no reference lines and so on. This is because Rizin requires every architecture plugin to provide also analysis information about every opcode. At the moment the implementation of disassembly and opcodes analysis is separated between two modules - RzAsm and RzAnalysis. Thus, we need to write an analysis plugin too. The principle is very similar - you just need to create a C file and corresponding Makefile.\nThey structure of RzAnalysis plugin looks like\nRzAnalysisPlugin rz_analysis_plugin_v810 = {\n .name = \"mycpu\",\n .desc = \"MYCPU code analysis plugin\",\n .license = \"LGPL3\",\n .arch = \"mycpu\",\n .bits = 32,\n .op = mycpu_op,\n .esil = true,\n .set_reg_profile = set_reg_profile,\n};\nLike with disassembly plugin there is a key function - mycpu_op which scans the opcode and builds RzAnalysisOp structure. On the other hand, in this example analysis plugins also performs uplifting to ESIL, which is enabled in .esil = true statement. Thus, mycpu_op obliged to fill the corresponding RzAnalysisOp ESIL field for the opcodes. Second important thing for ESIL uplifting and emulation - register profile, like in debugger, which is set within set_reg_profile function.\nMakefile\nNAME=analysis_mycpu\nRZ_PLUGIN_PATH=$(shell rizin -H RZ_USER_PLUGINS)\nLIBEXT=$(shell rizin -H LIBEXT)\nCFLAGS=-g -fPIC $(shell pkg-config --cflags rz_analysis)\nLDFLAGS=-shared $(shell pkg-config --libs rz_analysis)\nOBJS=$(NAME).o\nLIB=$(NAME).$(LIBEXT)\n\nall: $(LIB)\n\nclean:\n rm -f $(LIB) $(OBJS)\n\n$(LIB): $(OBJS)\n $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $(LIB)\n\ninstall:\n cp -f analysis_mycpu.$(SO_EXT) $(RZ_PLUGIN_PATH)\n\nuninstall:\n rm -f $(RZ_PLUGIN_PATH)/analysis_mycpu.$(SO_EXT)\nanalysis_mycpu.c: This is a dummy example please go check real life examples in the source.\n/* rizin - LGPL - Copyright 2022 - user */\n\n#include <string.h>\n#include <rz_types.h>\n#include <rz_lib.h>\n#include <rz_asm.h>\n#include <rz_analysis.h>\n\n#define NB_INST 2\n\ntypedef struct {\n const char *name;\n ut8 len;\n} mycpu_op_t;\n\nstatic mycpu_op_t mycpu_op[] = {\n /*00*/ { \"nop\", 2 }, //enough\n /*01*/ { \"ret\", 2 },\n}\n\nstatic int mycpu_anop(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len) {\n if (data[0] < NB_INST) {\n op->size = mycpu_op[data[0]].len;\n op->addr = addr;\n op->type = RZ_ANALYSIS_OP_TYPE_UNK;\n switch (data[0]) {\n case 0x00:\n op->type = RZ_ANALYSIS_OP_TYPE_NOP;\n break;\n case 0x01:\n op->type = RZ_ANALYSIS_OP_TYPE_RET;\n break;\n }\n return op->size;\n }\n}\n\nstruct rz_analysis_plugin_t rz_analysis_plugin_mycpu = {\n .name = \"mycpu\",\n .desc = \"MYCPU analysis plugin\",\n .license = \"LGPL3\",\n .arch = RZ_SYS_ARCH_NONE,\n .bits = 16,\n .init = NULL,\n .fini = NULL,\n .op = &mycpu_anop,\n .set_reg_profile = NULL,\n .fingerprint_bb = NULL,\n .fingerprint_fcn = NULL,\n .diff_bb = NULL,\n .diff_fcn = NULL,\n .diff_eval = NULL\n};\n\n#ifndef RZ_PLUGIN_INCORE\nRZ_API RzLibStruct rizin_plugin = {\n .type = RZ_LIB_TYPE_ANALYSIS,\n .data = &rz_analysis_plugin_mycpu,\n .version = RZ_VERSION\n};\n#endif\nAfter compiling rizin will list this plugin in the rz-asm output:\n_dA_ _8_16 mycpu LGPL3 MYCPU disassembly plugin\nNote the A just appeared on the left column (a=asm, d=disasm, A=analyze, e=ESIL).\nExamples:\n\nRzAnalysis plugin for 6502\nRzAnalysis plugin for SNES", "crumbs": [ "Plugins", - "100  Implementing a new analysis plugin" + "101  Implementing a new analysis plugin" ] }, { "objectID": "src/plugins/dev-bin.html", "href": "src/plugins/dev-bin.html", - "title": "101  Implementing a new format", + "title": "102  Implementing a new format", "section": "", - "text": "101.1 Create a folder with file format name in librz/bin/format\nMakefile:\nbin_nes.c:", + "text": "102.1 Create a folder with file format name in librz/bin/format\nMakefile:\nbin_nes.c:", "crumbs": [ "Plugins", - "101  Implementing a new format" + "102  Implementing a new format" ] }, { "objectID": "src/plugins/dev-bin.html#create-a-folder-with-file-format-name-in-librzbinformat", "href": "src/plugins/dev-bin.html#create-a-folder-with-file-format-name-in-librzbinformat", - "title": "101  Implementing a new format", + "title": "102  Implementing a new format", "section": "", - "text": "NAME=bin_nes\nRZ_PLUGIN_PATH=$(shell rizin -H RZ_USER_PLUGINS)\nLIBEXT=$(shell rizin -H LIBEXT)\nCFLAGS=-g -fPIC $(shell pkg-config --cflags rz_bin)\nLDFLAGS=-shared $(shell pkg-config --libs rz_bin)\nOBJS=$(NAME).o\nLIB=$(NAME).$(LIBEXT)\n\nall: $(LIB)\n\nclean:\n rm -f $(LIB) $(OBJS)\n\n$(LIB): $(OBJS)\n $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $(LIB)\n\ninstall:\n cp -f $(NAME).$(SO_EXT) $(RZ_PLUGIN_PATH)\n\nuninstall:\n rm -f $(RZ_PLUGIN_PATH)/$(NAME).$(SO_EXT)\n\n#include <rz_util.h>\n#include <rz_bin.h>\n\nstatic bool load_buffer(RzBinFile *bf, void **bin_obj, RzBuffer *b, ut64 loadaddr, Sdb *sdb) {\n ut64 size;\n const ut8 *buf = rz_buf_data (b, &size);\n rz_return_val_if_fail (buf, false);\n *bin_obj = rz_bin_internal_nes_load (buf, size);\n return *bin_obj != NULL;\n}\n\nstatic void destroy(RzBinFile *bf) {\n rz_bin_free_all_nes_obj (bf->o->bin_obj);\n bf->o->bin_obj = NULL;\n}\n\nstatic bool check_buffer(RzBuffer *b) {\n if (!buf || length < 4) return false;\n return (!memcmp (buf, \"\\x4E\\x45\\x53\\x1A\", 4));\n}\n\nstatic RzBinInfo* info(RzBinFile *arch) {\n RzBinInfo \\*ret = RZ_NEW0 (RzBinInfo);\n if (!ret) return NULL;\n\n if (!arch || !arch->buf) {\n free (ret);\n return NULL;\n }\n ret->file = strdup (arch->file);\n ret->type = strdup (\"ROM\");\n ret->machine = strdup (\"Nintendo NES\");\n ret->os = strdup (\"nes\");\n ret->arch = strdup (\"6502\");\n ret->bits = 8;\n\n return ret;\n}\n\nstruct rz_bin_plugin_t rz_bin_plugin_nes = {\n .name = \"nes\",\n .desc = \"NES\",\n .license = \"BSD\",\n .get_sdb = NULL,\n .load_buffer = &load_buffer,\n .destroy = &destroy,\n .check_buffer = &check_buffer,\n .baddr = NULL,\n .entries = NULL,\n .sections = NULL,\n .info = &info,\n};\n\n#ifndef RZ_PLUGIN_INCORE\nRZ_API RzLibStruct rizin_plugin = {\n .type = RZ_LIB_TYPE_BIN,\n .data = &rz_bin_plugin_nes,\n .version = RZ_VERSION\n};\n#endif\n\n101.1.1 Some Examples\n\nJava - https://github.com/rizinorg/rizin/commit/7cfddb1da8204587cdc1ba1a26bc07c9fee403dc\nZimgz - https://github.com/rizinorg/rizin/commit/d1351cf836df3e2e63043a6dc728e880316f00eb\nOMF - https://github.com/rizinorg/rizin/commit/44fd8b2555a0446ea759901a94c06f20566bbc40", + "text": "NAME=bin_nes\nRZ_PLUGIN_PATH=$(shell rizin -H RZ_USER_PLUGINS)\nLIBEXT=$(shell rizin -H LIBEXT)\nCFLAGS=-g -fPIC $(shell pkg-config --cflags rz_bin)\nLDFLAGS=-shared $(shell pkg-config --libs rz_bin)\nOBJS=$(NAME).o\nLIB=$(NAME).$(LIBEXT)\n\nall: $(LIB)\n\nclean:\n rm -f $(LIB) $(OBJS)\n\n$(LIB): $(OBJS)\n $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) -o $(LIB)\n\ninstall:\n cp -f $(NAME).$(SO_EXT) $(RZ_PLUGIN_PATH)\n\nuninstall:\n rm -f $(RZ_PLUGIN_PATH)/$(NAME).$(SO_EXT)\n\n#include <rz_util.h>\n#include <rz_bin.h>\n\nstatic bool load_buffer(RzBinFile *bf, void **bin_obj, RzBuffer *b, ut64 loadaddr, Sdb *sdb) {\n ut64 size;\n const ut8 *buf = rz_buf_data (b, &size);\n rz_return_val_if_fail (buf, false);\n *bin_obj = rz_bin_internal_nes_load (buf, size);\n return *bin_obj != NULL;\n}\n\nstatic void destroy(RzBinFile *bf) {\n rz_bin_free_all_nes_obj (bf->o->bin_obj);\n bf->o->bin_obj = NULL;\n}\n\nstatic bool check_buffer(RzBuffer *b) {\n if (!buf || length < 4) return false;\n return (!memcmp (buf, \"\\x4E\\x45\\x53\\x1A\", 4));\n}\n\nstatic RzBinInfo* info(RzBinFile *arch) {\n RzBinInfo \\*ret = RZ_NEW0 (RzBinInfo);\n if (!ret) return NULL;\n\n if (!arch || !arch->buf) {\n free (ret);\n return NULL;\n }\n ret->file = strdup (arch->file);\n ret->type = strdup (\"ROM\");\n ret->machine = strdup (\"Nintendo NES\");\n ret->os = strdup (\"nes\");\n ret->arch = strdup (\"6502\");\n ret->bits = 8;\n\n return ret;\n}\n\nstruct rz_bin_plugin_t rz_bin_plugin_nes = {\n .name = \"nes\",\n .desc = \"NES\",\n .license = \"BSD\",\n .get_sdb = NULL,\n .load_buffer = &load_buffer,\n .destroy = &destroy,\n .check_buffer = &check_buffer,\n .baddr = NULL,\n .entries = NULL,\n .sections = NULL,\n .info = &info,\n};\n\n#ifndef RZ_PLUGIN_INCORE\nRZ_API RzLibStruct rizin_plugin = {\n .type = RZ_LIB_TYPE_BIN,\n .data = &rz_bin_plugin_nes,\n .version = RZ_VERSION\n};\n#endif\n\n102.1.1 Some Examples\n\nJava - https://github.com/rizinorg/rizin/commit/7cfddb1da8204587cdc1ba1a26bc07c9fee403dc\nZimgz - https://github.com/rizinorg/rizin/commit/d1351cf836df3e2e63043a6dc728e880316f00eb\nOMF - https://github.com/rizinorg/rizin/commit/44fd8b2555a0446ea759901a94c06f20566bbc40", "crumbs": [ "Plugins", - "101  Implementing a new format" + "102  Implementing a new format" ] }, { "objectID": "src/plugins/dev-other.html", "href": "src/plugins/dev-other.html", - "title": "102  Write a debugger plugin", + "title": "103  Write a debugger plugin", "section": "", - "text": "102.1 More to come…\nIf you want to add support for the gdb, you can see the register profile in the active gdb session using command maint print registers.\nSome commits related to “Implementing a new architecture”", + "text": "103.1 More to come…\nIf you want to add support for the gdb, you can see the register profile in the active gdb session using command maint print registers.\nSome commits related to “Implementing a new architecture”", "crumbs": [ "Plugins", - "102  Write a debugger plugin" + "103  Write a debugger plugin" ] }, { "objectID": "src/plugins/dev-other.html#more-to-come", "href": "src/plugins/dev-other.html#more-to-come", - "title": "102  Write a debugger plugin", + "title": "103  Write a debugger plugin", "section": "", "text": "Related article: http://rizin.today/posts/extending-r2-with-new-plugins/\n\n\n\nExtensa: https://github.com/rizinorg/rizin/commit/6f1655c49160fe9a287020537afe0fb8049085d7\nMalbolge: https://github.com/rizinorg/rizin/pull/579\n6502: https://github.com/rizinorg/rizin/pull/656\nh8300: https://github.com/rizinorg/rizin/pull/664\nGBA: https://github.com/rizinorg/rizin/pull/702\nCR16: https://github.com/rizinorg/rizin/pull/721/ && 726\nXCore: https://github.com/rizinorg/rizin/commit/bb16d1737ca5a471142f16ccfa7d444d2713a54d\nSharpLH5801: https://github.com/neuschaefer/rizin/commit/f4993cca634161ce6f82a64596fce45fe6b818e7\nMSP430: https://github.com/rizinorg/rizin/pull/1426\nHP-PA-RISC: https://github.com/rizinorg/rizin/commit/f8384feb6ba019b91229adb8fd6e0314b0656f7b\nV810: https://github.com/rizinorg/rizin/pull/2899\nTMS320: https://github.com/rizinorg/rizin/pull/596", "crumbs": [ "Plugins", - "102  Write a debugger plugin" + "103  Write a debugger plugin" ] }, { "objectID": "src/plugins/dev-other.html#implementing-a-new-pseudo-architecture", "href": "src/plugins/dev-other.html#implementing-a-new-pseudo-architecture", - "title": "102  Write a debugger plugin", - "section": "102.2 Implementing a new pseudo architecture", - "text": "102.2 Implementing a new pseudo architecture\nThis is a simple plugin for z80 that you may use as example:\n\nhttps://github.com/rizinorg/rizin/commit/8ff6a92f65331cf8ad74cd0f44a60c258b137a06", + "title": "103  Write a debugger plugin", + "section": "103.2 Implementing a new pseudo architecture", + "text": "103.2 Implementing a new pseudo architecture\nThis is a simple plugin for z80 that you may use as example:\n\nhttps://github.com/rizinorg/rizin/commit/8ff6a92f65331cf8ad74cd0f44a60c258b137a06", "crumbs": [ "Plugins", - "102  Write a debugger plugin" + "103  Write a debugger plugin" ] }, { "objectID": "src/plugins/python.html", "href": "src/plugins/python.html", - "title": "103  Python plugins", + "title": "104  Python plugins", "section": "", - "text": "Note - in the following examples there are missing functions of the actual decoding for the sake of readability!\nFor this you need to do this:\n\nimport rzlang and from rzlang import RZ (for constants)\nMake a function with 2 subfunctions - assemble and disassemble and returning plugin structure - for RzAsm plugin\ndef mycpu(a):\n def assemble(s):\n return [1, 2, 3, 4]\n\n def disassemble(memview, addr):\n try:\n opcode = get_opcode(memview) # https://docs.python.org/3/library/stdtypes.html#memoryview\n opstr = optbl[opcode][1]\n return [4, opstr]\n except:\n return [4, \"unknown\"]\nThis structure should contain a pointers to these 2 functions - assemble and disassemble\n return {\n \"name\" : \"mycpu\",\n \"arch\" : \"mycpu\",\n \"bits\" : 32,\n \"endian\" : RZ.RZ_SYS_ENDIAN_LITTLE,\n \"license\" : \"GPL\",\n \"desc\" : \"MYCPU disasm\",\n \"assemble\" : assemble,\n \"disassemble\" : disassemble,\n }\nMake a function with 2 subfunctions - set_reg_profile and op and returning plugin structure - for RzAnalysis plugin\ndef mycpu_analysis(a):\n def set_reg_profile():\n profile = \"=PC pc\\n\" + \\\n \"=SP sp\\n\" + \\\n \"gpr r0 .32 0 0\\n\" + \\\n \"gpr r1 .32 4 0\\n\" + \\\n \"gpr r2 .32 8 0\\n\" + \\\n \"gpr r3 .32 12 0\\n\" + \\\n \"gpr r4 .32 16 0\\n\" + \\\n \"gpr r5 .32 20 0\\n\" + \\\n \"gpr sp .32 24 0\\n\" + \\\n \"gpr pc .32 28 0\\n\"\n return profile\n\n def op(memview, pc):\n analysisop = {\n \"type\" : RZ.RZ_ANALYSIS_OP_TYPE_NULL,\n \"cycles\" : 0,\n \"stackop\" : 0,\n \"stackptr\" : 0,\n \"ptr\" : -1,\n \"jump\" : -1,\n \"addr\" : 0,\n \"eob\" : False,\n \"esil\" : \"\",\n }\n try:\n opcode = get_opcode(memview) # https://docs.python.org/3/library/stdtypes.html#memoryview\n esilstr = optbl[opcode][2]\n if optbl[opcode][0] == \"J\": # it's jump\n analysisop[\"type\"] = RZ.RZ_ANALYSIS_OP_TYPE_JMP\n analysisop[\"jump\"] = decode_jump(opcode, j_mask)\n esilstr = jump_esil(esilstr, opcode, j_mask)\n\n except:\n result = analysisop\n # Don't forget to return proper instruction size!\n return [4, result]\nThis structure should contain a pointers to these 2 functions - set_reg_profile and op\n return {\n \"name\" : \"mycpu\",\n \"arch\" : \"mycpu\",\n \"bits\" : 32,\n \"license\" : \"GPL\",\n \"desc\" : \"MYCPU analysis\",\n \"esil\" : 1,\n \"set_reg_profile\" : set_reg_profile,\n \"op\" : op,\n }\nThen register those using rzlang.plugin(\"asm\") and rzlang.plugin(\"analysis\") respectively\nprint(\"Registering MYCPU disasm plugin...\")\nprint(rzlang.plugin(\"asm\", mycpu))\nprint(\"Registering MYCPU analysis plugin...\")\nprint(rzlang.plugin(\"analysis\", mycpu_analysis))\n\nYou can combine everything in one file and load it using -i option:\nrizin -I mycpu.py some_file.bin\nOr you can load it from the rizin shell: #!python mycpu.py\n\n103.0.1 Implementing new format plugin in Python\nNote - in the following examples there are missing functions of the actual decoding for the sake of readability!\nFor this you need to do this: 1. import rzlang\n\nMake a function with subfunctions:\n\nload\nload_bytes\ndestroy\ncheck_bytes\nbaddr\nentries\nsections\nimports\nrelocs\nbinsym\ninfo\n\nand returning plugin structure - for RzAsm plugin\ndef le_format(a):\n def load(binf):\n return [0]\n\n def check_bytes(buf):\n try:\n if buf[0] == 77 and buf[1] == 90:\n lx_off, = struct.unpack(\"<I\", buf[0x3c:0x40])\n if buf[lx_off] == 76 and buf[lx_off+1] == 88:\n return [1]\n return [0]\n except:\n return [0]\nand so on. Please be sure of the parameters for each function and format of returns. Note, that functions entries, sections, imports, relocs returns a list of special formed dictionaries - each with a different type. Other functions return just a list of numerical values, even if single element one. There is a special function, which returns information about the file - info:\n def info(binf):\n return [{\n \"type\" : \"le\",\n \"bclass\" : \"le\",\n \"rclass\" : \"le\",\n \"os\" : \"OS/2\",\n \"subsystem\" : \"CLI\",\n \"machine\" : \"IBM\",\n \"arch\" : \"x86\",\n \"has_va\" : 0,\n \"bits\" : 32,\n \"big_endian\" : 0,\n \"dbg_info\" : 0,\n }]\nThis structure should contain a pointers to the most important functions like check_bytes, load and load_bytes, entries, relocs, imports.\n return {\n \"name\" : \"le\",\n \"desc\" : \"OS/2 LE/LX format\",\n \"license\" : \"GPL\",\n \"load\" : load,\n \"load_bytes\" : load_bytes,\n \"destroy\" : destroy,\n \"check_bytes\" : check_bytes,\n \"baddr\" : baddr,\n \"entries\" : entries,\n \"sections\" : sections,\n \"imports\" : imports,\n \"symbols\" : symbols,\n \"relocs\" : relocs,\n \"binsym\" : binsym,\n \"info\" : info,\n }\nThen you need to register it as a file format plugin:\nprint(\"Registering OS/2 LE/LX plugin...\")\nprint(rzlang.plugin(\"bin\", le_format))", + "text": "Note - in the following examples there are missing functions of the actual decoding for the sake of readability!\nFor this you need to do this:\n\nimport rzlang and from rzlang import RZ (for constants)\nMake a function with 2 subfunctions - assemble and disassemble and returning plugin structure - for RzAsm plugin\ndef mycpu(a):\n def assemble(s):\n return [1, 2, 3, 4]\n\n def disassemble(memview, addr):\n try:\n opcode = get_opcode(memview) # https://docs.python.org/3/library/stdtypes.html#memoryview\n opstr = optbl[opcode][1]\n return [4, opstr]\n except:\n return [4, \"unknown\"]\nThis structure should contain a pointers to these 2 functions - assemble and disassemble\n return {\n \"name\" : \"mycpu\",\n \"arch\" : \"mycpu\",\n \"bits\" : 32,\n \"endian\" : RZ.RZ_SYS_ENDIAN_LITTLE,\n \"license\" : \"GPL\",\n \"desc\" : \"MYCPU disasm\",\n \"assemble\" : assemble,\n \"disassemble\" : disassemble,\n }\nMake a function with 2 subfunctions - set_reg_profile and op and returning plugin structure - for RzAnalysis plugin\ndef mycpu_analysis(a):\n def set_reg_profile():\n profile = \"=PC pc\\n\" + \\\n \"=SP sp\\n\" + \\\n \"gpr r0 .32 0 0\\n\" + \\\n \"gpr r1 .32 4 0\\n\" + \\\n \"gpr r2 .32 8 0\\n\" + \\\n \"gpr r3 .32 12 0\\n\" + \\\n \"gpr r4 .32 16 0\\n\" + \\\n \"gpr r5 .32 20 0\\n\" + \\\n \"gpr sp .32 24 0\\n\" + \\\n \"gpr pc .32 28 0\\n\"\n return profile\n\n def op(memview, pc):\n analysisop = {\n \"type\" : RZ.RZ_ANALYSIS_OP_TYPE_NULL,\n \"cycles\" : 0,\n \"stackop\" : 0,\n \"stackptr\" : 0,\n \"ptr\" : -1,\n \"jump\" : -1,\n \"addr\" : 0,\n \"eob\" : False,\n \"esil\" : \"\",\n }\n try:\n opcode = get_opcode(memview) # https://docs.python.org/3/library/stdtypes.html#memoryview\n esilstr = optbl[opcode][2]\n if optbl[opcode][0] == \"J\": # it's jump\n analysisop[\"type\"] = RZ.RZ_ANALYSIS_OP_TYPE_JMP\n analysisop[\"jump\"] = decode_jump(opcode, j_mask)\n esilstr = jump_esil(esilstr, opcode, j_mask)\n\n except:\n result = analysisop\n # Don't forget to return proper instruction size!\n return [4, result]\nThis structure should contain a pointers to these 2 functions - set_reg_profile and op\n return {\n \"name\" : \"mycpu\",\n \"arch\" : \"mycpu\",\n \"bits\" : 32,\n \"license\" : \"GPL\",\n \"desc\" : \"MYCPU analysis\",\n \"esil\" : 1,\n \"set_reg_profile\" : set_reg_profile,\n \"op\" : op,\n }\nThen register those using rzlang.plugin(\"asm\") and rzlang.plugin(\"analysis\") respectively\nprint(\"Registering MYCPU disasm plugin...\")\nprint(rzlang.plugin(\"asm\", mycpu))\nprint(\"Registering MYCPU analysis plugin...\")\nprint(rzlang.plugin(\"analysis\", mycpu_analysis))\n\nYou can combine everything in one file and load it using -i option:\nrizin -I mycpu.py some_file.bin\nOr you can load it from the rizin shell: #!python mycpu.py\n\n104.0.1 Implementing new format plugin in Python\nNote - in the following examples there are missing functions of the actual decoding for the sake of readability!\nFor this you need to do this: 1. import rzlang\n\nMake a function with subfunctions:\n\nload\nload_bytes\ndestroy\ncheck_bytes\nbaddr\nentries\nsections\nimports\nrelocs\nbinsym\ninfo\n\nand returning plugin structure - for RzAsm plugin\ndef le_format(a):\n def load(binf):\n return [0]\n\n def check_bytes(buf):\n try:\n if buf[0] == 77 and buf[1] == 90:\n lx_off, = struct.unpack(\"<I\", buf[0x3c:0x40])\n if buf[lx_off] == 76 and buf[lx_off+1] == 88:\n return [1]\n return [0]\n except:\n return [0]\nand so on. Please be sure of the parameters for each function and format of returns. Note, that functions entries, sections, imports, relocs returns a list of special formed dictionaries - each with a different type. Other functions return just a list of numerical values, even if single element one. There is a special function, which returns information about the file - info:\n def info(binf):\n return [{\n \"type\" : \"le\",\n \"bclass\" : \"le\",\n \"rclass\" : \"le\",\n \"os\" : \"OS/2\",\n \"subsystem\" : \"CLI\",\n \"machine\" : \"IBM\",\n \"arch\" : \"x86\",\n \"has_va\" : 0,\n \"bits\" : 32,\n \"big_endian\" : 0,\n \"dbg_info\" : 0,\n }]\nThis structure should contain a pointers to the most important functions like check_bytes, load and load_bytes, entries, relocs, imports.\n return {\n \"name\" : \"le\",\n \"desc\" : \"OS/2 LE/LX format\",\n \"license\" : \"GPL\",\n \"load\" : load,\n \"load_bytes\" : load_bytes,\n \"destroy\" : destroy,\n \"check_bytes\" : check_bytes,\n \"baddr\" : baddr,\n \"entries\" : entries,\n \"sections\" : sections,\n \"imports\" : imports,\n \"symbols\" : symbols,\n \"relocs\" : relocs,\n \"binsym\" : binsym,\n \"info\" : info,\n }\nThen you need to register it as a file format plugin:\nprint(\"Registering OS/2 LE/LX plugin...\")\nprint(rzlang.plugin(\"bin\", le_format))", "crumbs": [ "Plugins", - "103  Python plugins" + "104  Python plugins" ] }, { "objectID": "src/plugins/debug.html", "href": "src/plugins/debug.html", - "title": "104  Debugging", + "title": "105  Debugging", "section": "", "text": "It is common to have an issues when you write a plugin, especially if you do this for the first time. This is why debugging them is very important. The first step for debugging is to set an environment variable when running Rizin instance:\nR_DEBUG=yes rizin /bin/ls\nLoading /usr/local/lib/rizin/2.2.0-git//bin_xtr_dyldcache.so\nCannot find symbol 'rizin_plugin' in library '/usr/local/lib/rizin/2.2.0-git//bin_xtr_dyldcache.so'\nCannot open /usr/local/lib/rizin/2.2.0-git//2.2.0-git\nLoading /home/user/.config/rizin/plugins/asm_mips_ks.so\nPLUGIN OK 0x55b205ea6070 fcn 0x7f298de08762\nLoading /home/user/.config/rizin/plugins/asm_sparc_ks.so\nPLUGIN OK 0x55b205ea6070 fcn 0x7f298de08762\nCannot open /home/user/.config/rizin/plugins/pimp\nCannot open /home/user/.config/rizin/plugins/yara\nLoading /home/user/.config/rizin/plugins/asm_arm_ks.so\nPLUGIN OK 0x55b205ea6070 fcn 0x7f298de08762\nLoading /home/user/.config/rizin/plugins/core_yara.so\nModule version mismatch /home/user/.config/rizin/plugins/core_yara.so (2.1.0) vs (2.2.0-git)\nLoading /home/user/.config/rizin/plugins/asm_ppc_ks.so\nPLUGIN OK 0x55b205ea6070 fcn 0x7f298de08762\nLoading /home/user/.config/rizin/plugins/lang_python3.so\nPLUGIN OK 0x55b205ea5ed0 fcn 0x7f298de08692\nLoading /usr/local/lib/rizin/2.2.0-git/bin_xtr_dyldcache.so\nCannot find symbol 'rizin_plugin' in library '/usr/local/lib/rizin/2.2.0-git/bin_xtr_dyldcache.so'\nCannot open /usr/local/lib/rizin/2.2.0-git/2.2.0-git\nCannot open directory '/usr/local/lib/rizin-extras/2.2.0-git'\nCannot open directory '/usr/local/lib/rizin-bindings/2.2.0-git'\nUSER CONFIG loaded from /home/user/.config/rizin/rizinrc\n -- In visual mode press 'c' to toggle the cursor mode. Use tab to navigate\n[0x00005520]>", "crumbs": [ "Plugins", - "104  Debugging" + "105  Debugging" ] }, { "objectID": "src/plugins/testing.html", "href": "src/plugins/testing.html", - "title": "105  Testing the plugin", + "title": "106  Testing the plugin", "section": "", "text": "This plugin is used by rz-asm and rizin. You can verify that the plugin is properly loaded with this command:\n$ rz-asm -L | grep mycpu\n_d mycpu My CPU disassembler (LGPL3)\nLet’s open an empty file using the ‘mycpu’ arch and write some random code there.\n$ rizin =\n -- I endians swap\n[0x00000000]> e asm.arch=mycpu\n[0x00000000]> woR\n[0x00000000]> pd 10\n 0x00000000 888e mov r8, 14\n 0x00000002 b2a5 ifnot r10, r5\n 0x00000004 3f67 ret\n 0x00000006 7ef6 bl r15, r6\n 0x00000008 2701 xor r0, 1\n 0x0000000a 9826 mov r2, 6\n 0x0000000c 478d xor r8, 13\n 0x0000000e 6b6b store r6, 11\n 0x00000010 1382 add r8, r2\n 0x00000012 7f15 ret\nYay! It works… and the mandatory oneliner too!\nrizin -nqamycpu -cwoR -cpd' 10' =", "crumbs": [ "Plugins", - "105  Testing the plugin" + "106  Testing the plugin" ] }, { "objectID": "src/plugins/rz-pm.html", "href": "src/plugins/rz-pm.html", - "title": "106  Creating an rz-pm package of the plugin", + "title": "107  Creating an rz-pm package of the plugin", "section": "", "text": "Rizin has its own packaging manager, and we can easily add newly written plugin for everyone to access.\nAll packages are located in rizin-pm repository, and have very simple text format.\nRZPM_BEGIN\n\nRZPM_GIT \"https://github.com/user/mycpu\"\nRZPM_DESC \"[rizin-arch] MYCPU disassembler and analyzer plugins\"\n\nRZPM_INSTALL() {\n ${MAKE} clean\n ${MAKE} all || exit 1\n ${MAKE} install RZPM_PLUGDIR=\"${RZPM_PLUGDIR}\"\n}\n\nRZPM_UNINSTALL() {\n rm -f \"${RZPM_PLUGDIR}/asm_mycpu.\"*\n rm -f \"${RZPM_PLUGDIR}/analysis_mycpu.\"*\n}\n\nRZPM_END\nThen add it in the /db directory of rizin-pm repository and send a pull request to the mainline.", "crumbs": [ "Plugins", - "106  Creating an rz-pm package of the plugin" + "107  Creating an rz-pm package of the plugin" ] }, { "objectID": "src/crackmes/intro.html", "href": "src/crackmes/intro.html", - "title": "107  Crackmes", + "title": "108  Crackmes", "section": "", "text": "Crackmes (from “crack me” challenge) are the training ground for reverse engineering people. This section will go over tutorials on how to defeat various crackmes using Rizin.", "crumbs": [ "Crackmes", - "107  Crackmes" + "108  Crackmes" ] }, { "objectID": "src/crackmes/ioli/intro.html", "href": "src/crackmes/ioli/intro.html", - "title": "108  IOLI CrackMes", + "title": "109  IOLI CrackMes", "section": "", "text": "The IOLI crackme is a good starting point for learning Rizin. This is a set of tutorials based on the tutorial at dustri\nThe IOLI crackmes are available at a locally hosted mirror", "crumbs": [ "Crackmes", - "108  IOLI CrackMes" + "109  IOLI CrackMes" ] }, { "objectID": "src/crackmes/ioli/ioli_0x00.html", "href": "src/crackmes/ioli/ioli_0x00.html", - "title": "109  IOLI 0x00", + "title": "110  IOLI 0x00", "section": "", "text": "This is the first IOLI crackme, and the easiest one.\n$ ./crackme0x00\nIOLI Crackme Level 0x00\nPassword: 1234\nInvalid Password!\nThe first thing to check is if the password is just plaintext inside the file. In this case, we don’t need to do any disassembly, and we can just use rz-bin with the -z flag to search for strings in the binary.\n$ rz-bin -z ./crackme0x00\n[Strings]\nnth paddr vaddr len size section type string \n---------------------------------------------------------------------------\n0 0x00000568 0x08048568 24 25 .rodata ascii IOLI Crackme Level 0x00\\n\n1 0x00000581 0x08048581 10 11 .rodata ascii Password: \n2 0x0000058f 0x0804858f 6 7 .rodata ascii 250382\n3 0x00000596 0x08048596 18 19 .rodata ascii Invalid Password!\\n\n4 0x000005a9 0x080485a9 15 16 .rodata ascii Password OK :)\\n\nSo we know what the following section is: this section is the header shown when the application is run.\nnth paddr vaddr len size section type string\n―――――――――――――――――――――――――――――――――――――――――――――――――――――――\n0 0x00000568 0x08048568 24 25 .rodata ascii IOLI Crackme Level 0x00\\n\nHere we have the prompt for the password.\n1 0x00000581 0x08048581 10 11 .rodata ascii Password:\nThis is the error on entering an invalid password.\n3 0x00000596 0x08048596 18 19 .rodata ascii Invalid Password!\\n\nThis is the message on the password being accepted.\n4 0x000005a9 0x080485a9 15 16 .rodata ascii Password OK :)\\n\nWhat is this? It’s a string, but we haven’t seen it in running the application yet.\n2 0x0000058f 0x0804858f 6 7 .rodata ascii 250382\nLet’s give this a shot.\n$ ./crackme0x00\nIOLI Crackme Level 0x00\nPassword: 250382\nPassword OK :)\nSo we now know that 250382 is the password, and have completed this crackme.", "crumbs": [ "Crackmes", - "109  IOLI 0x00" + "110  IOLI 0x00" ] }, { "objectID": "src/crackmes/ioli/ioli_0x01.html", "href": "src/crackmes/ioli/ioli_0x01.html", - "title": "110  IOLI 0x01", + "title": "111  IOLI 0x01", "section": "", "text": "This is the second IOLI crackme.\n$ ./crackme0x01\nIOLI Crackme Level 0x01\nPassword: test\nInvalid Password!\nLet’s check for strings with rz-bin.\n$ rz-bin -z ./crackme0x01\n[Strings]\nnth paddr vaddr len size section type string \n---------------------------------------------------------------------------\n0 0x00000528 0x08048528 24 25 .rodata ascii IOLI Crackme Level 0x01\\n\n1 0x00000541 0x08048541 10 11 .rodata ascii Password: \n2 0x0000054f 0x0804854f 18 19 .rodata ascii Invalid Password!\\n\n3 0x00000562 0x08048562 15 16 .rodata ascii Password OK :)\\n\nThis isn’t going to be as easy as 0x00. Let’s try disassembly with rizin.\n$ rizin ./crackme0x01\n[0x08048330]> aa\n[0x08048330]> pdf @ main\n ; DATA XREF from entry0 @ 0x8048347\n/ int main(int argc, char **argv, char **envp);\n| ; var int32_t var_18h @ stack - 0x18\n| ; var int32_t var_8h @ stack - 0x8\n| 0x080483e4 push ebp\n| 0x080483e5 mov ebp, esp\n| 0x080483e7 sub esp, 0x18\n| 0x080483ea and esp, 0xfffffff0\n| 0x080483ed mov eax, 0\n| 0x080483f2 add eax, 0xf ; 15\n| 0x080483f5 add eax, 0xf ; 15\n| 0x080483f8 shr eax, 4\n| 0x080483fb shl eax, 4\n| 0x080483fe sub esp, eax\n| 0x08048400 mov dword [esp], str.IOLI_Crackme_Level_0x01 ; [0x8048528:4]=0x494c4f49 ; \"IOLI Crackme Level 0x01\\n\"\n| 0x08048407 call sym.imp.printf ; sym.imp.printf ; int printf(const char *format)\n| 0x0804840c mov dword [esp], str.Password: ; [0x8048541:4]=0x73736150 ; \"Password: \"\n| 0x08048413 call sym.imp.printf ; sym.imp.printf ; int printf(const char *format)\n| 0x08048418 lea eax, [var_8h]\n| 0x0804841b mov dword [var_18h], eax\n| 0x0804841f mov dword [esp], 0x804854c ; [0x804854c:4]=0x49006425\n| 0x08048426 call sym.imp.scanf ; sym.imp.scanf ; int scanf(const char *format)\n| 0x0804842b cmp dword [var_8h], 0x149a\n| ,=< 0x08048432 je 0x8048442\n| | 0x08048434 mov dword [esp], str.Invalid_Password ; [0x804854f:4]=0x61766e49 ; \"Invalid Password!\\n\"\n| | 0x0804843b call sym.imp.printf ; sym.imp.printf ; int printf(const char *format)\n| ,==< 0x08048440 jmp 0x804844e\n| |`-> 0x08048442 mov dword [esp], str.Password_OK_: ; [0x8048562:4]=0x73736150 ; \"Password OK :)\\n\"\n| | 0x08048449 call sym.imp.printf ; sym.imp.printf ; int printf(const char *format)\n| | ; CODE XREF from main @ 0x8048440\n| `--> 0x0804844e mov eax, 0\n| 0x08048453 leave\n\\ 0x08048454 ret\n“aa” tells Rizin to analyze the whole binary, which gets you symbol names, among things.\n“pdf” stands for print, disassemble, function.\nThis will print the disassembly of the main function, or the main() that everyone knows. You can see several things as well: weird names, arrows, etc.\n\n“imp.” stands for imports. Those are imported symbols, like printf()\n“str.” stands for strings. Those are strings (obviously).\n\nIf you look carefully, you’ll see a cmp instruction, with a constant, 0x149a. cmp is an x86 compare instruction, and the 0x in front of it specifies it is in base 16, or hex (hexadecimal).\n│ 0x0804842b cmp dword [var_8h], 0x149a\nYou can use rizin’s % command to display 0x149a in another numeric base.\n[0x08048330]> % 0x149a\nint32 5274\nuint32 5274\nhex 0x149a\noctal 012232\nunit 5.2K\nsegment 0000:049a\nstring \"\\x9a\\x14\"\nfvalue 5274.0\nfloat 5274.000000f\ndouble 5274.000000\nbinary 0b0001010010011010\ntrits 0t21020100\nSo now we know that 0x149a is 5274 in decimal. Let’s try this as a password.\n$ ./crackme0x01\nIOLI Crackme Level 0x01\nPassword: 5274\nPassword OK :)\nBingo, the password was 5274. In this case, the password function at 0x0804842b was comparing the input against the value, 0x149a in hex. Since user input is usually decimal, it was a safe bet that the input was intended to be in decimal, or 5274. Now, since we’re hackers, and curiosity drives us, let’s see what happens when we input in hex.\n$ ./crackme0x01\nIOLI Crackme Level 0x01\nPassword: 0x149a\nInvalid Password!\nIt was worth a shot, but it doesn’t work. That’s because scanf() will take the 0 in 0x149a to be a zero, rather than accepting the input as actually being the hex value.\nAnd this concludes IOLI 0x01.", "crumbs": [ "Crackmes", - "110  IOLI 0x01" + "111  IOLI 0x01" ] }, { "objectID": "src/crackmes/ioli/ioli_0x02.html", "href": "src/crackmes/ioli/ioli_0x02.html", - "title": "111  IOLI 0x02", + "title": "112  IOLI 0x02", "section": "", "text": "This is the third one.\n$ ./crackme0x02\nIOLI Crackme Level 0x02\nPassword: hello\nInvalid Password!\nFirstly, let’s check it with rz-bin.\n$ rz-bin -z ./crackme0x02\n[Strings]\nnth paddr vaddr len size section type string \n---------------------------------------------------------------------------\n0 0x00000548 0x08048548 24 25 .rodata ascii IOLI Crackme Level 0x02\\n\n1 0x00000561 0x08048561 10 11 .rodata ascii Password: \n2 0x0000056f 0x0804856f 15 16 .rodata ascii Password OK :)\\n\n3 0x0000057f 0x0804857f 18 19 .rodata ascii Invalid Password!\\n\nSimilar to 0x01, there’s no explicit password string here. So, it’s time to analyze it with Rizin.\n$ rizin ./crackme0x02\n[0x08048330]> aa\n[x] Analyze all flags starting with sym. and entry0 (aa)\n[0x08048330]> pdf @ main\n ; DATA XREF from entry0 @ 0x8048347\n/ int main(int argc, char **argv, char **envp);\n| ; var int32_t var_18h @ stack - 0x18\n| ; var int32_t var_10h @ stack - 0x10\n| ; var int32_t var_ch @ stack - 0xc\n| ; var int32_t var_8h @ stack - 0x8\n| 0x080483e4 push ebp\n| 0x080483e5 mov ebp, esp\n| 0x080483e7 sub esp, 0x18\n| 0x080483ea and esp, 0xfffffff0\n| 0x080483ed mov eax, 0\n| 0x080483f2 add eax, 0xf ; 15\n| 0x080483f5 add eax, 0xf ; 15\n| 0x080483f8 shr eax, 4\n| 0x080483fb shl eax, 4\n| 0x080483fe sub esp, eax\n| 0x08048400 mov dword [esp], str.IOLI_Crackme_Level_0x02 ; [0x8048548:4]=0x494c4f49 ; \"IOLI Crackme Level 0x02\\n\"\n| 0x08048407 call sym.imp.printf ; sym.imp.printf ; int printf(const char *format)\n| 0x0804840c mov dword [esp], str.Password: ; [0x8048561:4]=0x73736150 ; \"Password: \"\n| 0x08048413 call sym.imp.printf ; sym.imp.printf ; int printf(const char *format)\n| 0x08048418 lea eax, [var_8h]\n| 0x0804841b mov dword [var_18h], eax\n| 0x0804841f mov dword [esp], 0x804856c ; [0x804856c:4]=0x50006425\n| 0x08048426 call sym.imp.scanf ; sym.imp.scanf ; int scanf(const char *format)\n| 0x0804842b mov dword [var_ch], 0x5a ; 'Z' ; 90\n| 0x08048432 mov dword [var_10h], 0x1ec ; 492\n| 0x08048439 mov edx, dword [var_10h]\n| 0x0804843c lea eax, [var_ch]\n| 0x0804843f add dword [eax], edx\n| 0x08048441 mov eax, dword [var_ch]\n| 0x08048444 imul eax, dword [var_ch]\n| 0x08048448 mov dword [var_10h], eax\n| 0x0804844b mov eax, dword [var_8h]\n| 0x0804844e cmp eax, dword [var_10h]\n| ,=< 0x08048451 jne 0x8048461\n| | 0x08048453 mov dword [esp], str.Password_OK_: ; [0x804856f:4]=0x73736150 ; \"Password OK :)\\n\"\n| | 0x0804845a call sym.imp.printf ; sym.imp.printf ; int printf(const char *format)\n| ,==< 0x0804845f jmp 0x804846d\n| |`-> 0x08048461 mov dword [esp], str.Invalid_Password ; [0x804857f:4]=0x61766e49 ; \"Invalid Password!\\n\"\n| | 0x08048468 call sym.imp.printf ; sym.imp.printf ; int printf(const char *format)\n| | ; CODE XREF from main @ 0x804845f\n| `--> 0x0804846d mov eax, 0\n| 0x08048472 leave\n\\ 0x08048473 ret\nWith the experience of solving crackme0x01, we can first locate the position of cmp instruction by using this simple oneliner:\n[0x08048330]> pdf @ main~cmp\n│ 0x0804844e cmp eax, dword [var_10h]\nUnfortunately, the variable compared to eax is stored in the stack. We can’t check the value of this variable directly. It’s a common case in reverse engineering that we have to derive the value of the variable from the previous sequence. As the amount of code is relatively small, it can be easily done.\nfor example:\n│ 0x080483ed mov eax, 0\n│ 0x080483f2 add eax, 0xf ; 15\n│ 0x080483f5 add eax, 0xf ; 15\n│ 0x080483f8 shr eax, 4\n│ 0x080483fb shl eax, 4\n│ 0x080483fe sub esp, eax\nWe can easily get the value of eax. It’s 16.\nDirectly looking at the disassembly gets hard when the scale of program grows. Rizin’s flagship decompiler rz-ghidra might be of help, here. You can install it easily:\nrz-pm -i rz-ghidra\nDecompile main() with the following command (like F5 in IDA):\n[0x080483e4]> pdg @ main\n\nundefined4 main(void)\n{\n int32_t var_18h;\n int32_t var_10h;\n int32_t var_ch;\n int32_t var_8h;\n \n sym.imp.printf(\"IOLI Crackme Level 0x02\\n\");\n sym.imp.printf(\"Password: \");\n sym.imp.scanf(0x804856c, &var_8h);\n if (var_8h == 0x52b24) {\n sym.imp.printf(\"Password OK :)\\n\");\n } else {\n sym.imp.printf(\"Invalid Password!\\n\");\n }\n return 0;\n}\nIt’s more human-readable now. To check the string in 0x804856c, we can: * Seek * Print the string *\n[0x080483e4]> s 0x804856c\n[0x0804856c]> ps\n%d\nIt’s exactly the format string of scanf(). And rz-ghidra recognizes that the second argument (eax) is a pointer, and it points to var_8h. Which means our input will be stored in var_8h.\nWe can easily write out the pseudocode here.\nvar_ch = (var_8h + var_ch)^2;\nif (var_ch == our_input)\n printf(\"Password OK :)\\n\");\nGiven the initial status that var_8h is 0x5a, var_ch is 0x1ec, we have var_ch = 338724 (0x52b24):\n$ rz-ax '=10' '(0x5a+0x1ec)*(0x5a+0x1ec)'\n338724\n\n$ ./crackme0x02\nIOLI Crackme Level 0x02\nPassword: 338724\nPassword OK :)\nAnd we finish the crackme0x02.", "crumbs": [ "Crackmes", - "111  IOLI 0x02" + "112  IOLI 0x02" ] }, { "objectID": "src/crackmes/ioli/ioli_0x03.html", "href": "src/crackmes/ioli/ioli_0x03.html", - "title": "112  IOLI 0x03", + "title": "113  IOLI 0x03", "section": "", "text": "This is the fourth crackme.\n$ ./crackme0x03\nIOLI Crackme Level 0x03\nPassword: letmein\nInvalid Password!\nChecking for strings with rz-bin -z ./crackme0x03 gives us the following result:\n$ rz-bin -z ./crackme0x03\n[Strings]\nnth paddr vaddr len size section type string \n---------------------------------------------------------------------------\n0 0x000005ec 0x080485ec 17 18 .rodata ascii Lqydolg#Sdvvzrug$\n1 0x000005fe 0x080485fe 17 18 .rodata ascii Sdvvzrug#RN$$$#=,\n2 0x00000610 0x08048610 24 25 .rodata ascii IOLI Crackme Level 0x03\\n\n3 0x00000629 0x08048629 10 11 .rodata ascii Password: \nNote that the ‘Invalid Password!’ and the ‘Password OK :)’ strings have been seemingly replaced by random gibberish.\nLet’s analyze.\n$ rizin ./crackme0x03\n[0x08048360]> aaa\n[0x08048360]> pdg @ main\n\nundefined4 main(void)\n{\n int32_t var_18h;\n int32_t var_10h;\n int32_t var_ch;\n int32_t var_8h;\n \n sym.imp.printf(\"IOLI Crackme Level 0x03\\n\");\n sym.imp.printf(\"Password: \");\n sym.imp.scanf(data.08048634, &var_8h);\n sym.test(var_8h, 0x52b24);\n return 0;\n}\nThis looks quite straightforward, var_8h is the result of scanf which the function sym.test(var_8h, 0x52b24) apparently compares to the value 0x52b24.\nAnd indeed entering the decimal value of 0x52b24 (338724) gives us a pass.\n$ ./crackme0x03\nIOLI Crackme Level 0x03\nPassword: 338724\nPassword OK!!! :)\nBut let’s dive a bit deeper to see what sym.test() is actually doing!\n[0x08048360]> pdg @ sym.test\n\nvoid sym.test(int32_t arg_4h, unsigned long arg_8h)\n{\n if (arg_4h == arg_8h) {\n sym.shift(\"Sdvvzrug#RN$$$#=,\");\n } else {\n sym.shift(\"Lqydolg#Sdvvzrug$\");\n }\n return;\n}\nIt’s a two path conditional jump which compares two parameters and then does a shift. We can guess that shift() is most likely some sort of decoding step of the seemingly random strings (shift cipher, e.g. Caesar cipher).\nTo confirm our suspicions let’s analyze sym.shift().\n[0x08048360]> pdg @ sym.shift\n\n// WARNING: Variable defined which should be unmapped: var_98h\n\nvoid sym.shift(char *s)\n{\n uint32_t uVar1;\n int32_t var_98h;\n unsigned long var_80h;\n int32_t var_7ch;\n \n var_80h = 0;\n while( true ) {\n uVar1 = sym.imp.strlen(s);\n if (uVar1 <= var_80h) break;\n *(char *)((int32_t)&var_7ch + var_80h) = s[var_80h] + -3;\n var_80h = var_80h + 1;\n }\n *(undefined *)((int32_t)&var_7ch + var_80h) = 0;\n sym.imp.printf(data.080485e8, &var_7ch);\n return;\n}\nIf we clean this up a bit it becomes more evident what is going on.\nvoid shift(char *str)\n{\n uint32_t len = strlen(str);\n char res[len + 1];\n \n int32_t idx = 0;\n while( idx < len ) {\n res[idx] = str[idx] - 3; // Subtract character code by 3\n idx++;\n }\n res[idx] = 0; // Add null terminator\n printf(\"%s\\n\", res);\n return;\n}\nWe can see that each character in str is subtracted by 3 to produce the final result.\nWith this knowledge we can take a shot at decoding the strings. We can use the pos command to apply the subtraction needed for decoding and printing the result.\n$ rizin ./crackme0x03\n[0x08048360]> aaa\n[0x08048360]> fs strings\n[0x08048360]> fl\n0x080485ec 18 str.Lqydolg_Sdvvzrug\n0x080485fe 18 str.Sdvvzrug_RN\n0x08048610 25 str.IOLI_Crackme_Level_0x03\n0x08048629 11 str.Password:\n[0x08048360]> pos 0x03 @ str.Lqydolg_Sdvvzrug @! 18\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\n0x080485ec 496e 7661 6c69 6420 5061 7373 776f 7264 Invalid Password\n0x080485fc 21fd !.\n[0x08048360]> pos 0x03 @ str.Sdvvzrug_RN @! 18\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\n0x080485fe 5061 7373 776f 7264 204f 4b21 2121 203a Password OK!!! :\n0x0804860e 29fd ).\nHowever, some functions may not be as easy to understand as this one, in which case it may be useful to be able to run the code. Rizin provides us two ways of doing this: by using the debugger, or by emulation (using ESIL).\nLet’s first see how we can achieve this using the debugger. We will be wanting to pass the encoded strings to shift(). We know shift takes one parameter s, which is an address to a (null terminated) string. We can see where on the stack local variables and arguments are using the afvl command.\n$ rizin -d ./crackme0x03\n[0xf7f04630]> aa\n[0xf7f04630]> afvl @ sym.shift\nvar int32_t var_98h @ stack - 0x98\nvar int32_t var_80h @ stack - 0x80\nvar int32_t var_7ch @ stack - 0x7c\narg int32_t arg_4h @ stack + 0x4\nWe can see that s starts at a 4 byte offset from the stack pointer.\n[0xf7f04630]> dcu main # run until program start\nContinue until 0x08048498\nhit breakpoint at: 0x8048498\n[0x08048498]> *esp+4=str.Lqydolg_Sdvvzrug # 'push' address onto the stack (note the 4 byte offset)\n[0x08048498]> dr eip=sym.shift # set instruction pointer to start of shift()\n[0x08048498]> dcr # run shift() until it returns\nInvalid Password!\n[0x0804846d]> *esp+4=str.Sdvvzrug_RN # and now for the other string\n[0x08048498]> dr eip=sym.shift\n[0x08048498]> dcr\nPassword OK!!! :)\nEmulation is a bit more tricky because we can’t make external calls to functions like strlen() and printf(). So we have to manually skip over them and set the registers accordingly. Below is an example.\n[0x08048414]> s 0x08048445 # the 'sub al, 0x03'\n[0x08048445]> aei # init VM\n[0x08048445]> aeim # init memory\n[0x08048445]> aeip # init ip\n[0x08048445]> ar eax=0x41 # set eax=0x41 -- 'A'\n[0x08048445]> ar # show current value of regs\noeax = 0x00000000\neax = 0x00000041\nebx = 0x00000000\necx = 0x00000000\nedx = 0x00000000\nesi = 0x00000000\nedi = 0x00000000\nesp = 0x00178000\nebp = 0x00178000\neip = 0x08048445\neflags = 0x00000000\n[0x08048445]> V # enter Visual mode\n# 'p' or 'P' to change visual mode\n# I prefer the [xaDvc] mode\n# use 's' to step in and 'S' to step over\n[0x08048442 [xaDvc]0 0% 265 ./crackme0x03]> diq;?0;f t.. @ sym.shift+46 # 0x8048442\ndead at 0x00000000\n- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF\n0x00178000 0000 0000 0000 0000 0000 0000 0000 0000 ................\n0x00178010 0000 0000 0000 0000 0000 0000 0000 0000 ................\n0x00178020 0000 0000 0000 0000 0000 0000 0000 0000 ................\n0x00178030 0000 0000 0000 0000 0000 0000 0000 0000 ................\n oeax 0x00000000 eax 0x00000041 ebx 0x00000000 ecx 0x00000000\n edx 0x00000000 esi 0x00000000 edi 0x00000000 esp 0x00178000\n ebp 0x00178000 eip 0x08048445 eflags 0x00000000\n : 0x08048442 0fb600 movzx eax, byte [eax]\n : ;-- eip:\n : 0x08048445 2c03 sub al, 3\n : 0x08048447 8802 mov byte [edx], al\n : 0x08048449 8d4584 lea eax, [var_7ch]\n : 0x0804844c ff00 inc dword [eax]\n :=< 0x0804844e ebd4 jmp 0x8048424\n ; CODE XREF from sym.shift @ 0x8048432\n 0x08048450 8d4588 lea eax, [var_78h]", "crumbs": [ "Crackmes", - "112  IOLI 0x03" + "113  IOLI 0x03" ] }, { "objectID": "src/crackmes/ioli/ioli_0x04.html", "href": "src/crackmes/ioli/ioli_0x04.html", - "title": "113  IOLI 0x04", + "title": "114  IOLI 0x04", "section": "", "text": "This is the fifth crackme.\n$ rz-bin -z ./crackme0x04\n[Strings]\nnth paddr vaddr len size section type string \n---------------------------------------------------------------------------\n0 0x0000063b 0x0804863b 13 14 .rodata ascii Password OK!\\n\n1 0x00000649 0x08048649 20 21 .rodata ascii Password Incorrect!\\n\n2 0x0000065e 0x0804865e 24 25 .rodata ascii IOLI Crackme Level 0x04\\n\n3 0x00000677 0x08048677 10 11 .rodata ascii Password: \nChecking for strings we see that our old friends “Password OK!” and “Password Incorrect!” are back in their unobfuscated forms.\n$ rizin ./crackme0x04\n[0x080483d0]> aaa\n[0x080483d0]> pdg @ main\n\nundefined4 main(void)\n{\n int32_t var_88h;\n int32_t var_7ch;\n \n sym.imp.printf(\"IOLI Crackme Level 0x04\\n\");\n sym.imp.printf(\"Password: \");\n sym.imp.scanf(data.08048682, &var_7ch);\n sym.check((char *)&var_7ch);\n return 0;\n}\n[0x080483d0]> ps @ data.08048682 \n%s\nThis time though, scanf takes a string and passes it to a function called check.\n[0x080483d0]> pdg @ sym.check\n\n// WARNING: Variable defined which should be unmapped: format\n// WARNING: Variable defined which should be unmapped: args\n\nvoid sym.check(char *s)\n{\n uint32_t uVar1;\n char *format;\n va_list args;\n char *var_11h;\n unsigned long var_ch;\n int32_t var_8h;\n \n var_ch = 0;\n stack0xfffffff0 = 0;\n while( true ) {\n uVar1 = sym.imp.strlen(s);\n if (uVar1 <= stack0xfffffff0) break;\n var_11h._0_1_ = s[stack0xfffffff0];\n sym.imp.sscanf(&var_11h, data.08048638, &var_8h);\n var_ch = var_ch + var_8h;\n if (var_ch == 0xf) {\n sym.imp.printf(\"Password OK!\\n\");\n sym.imp.exit(0);\n }\n unique0x00003f80 = stack0xfffffff0 + 1;\n }\n sym.imp.printf(\"Password Incorrect!\\n\");\n return;\n}\n\n[0x080483d0]> afvl @ sym.check\nvar const char *format @ stack - 0x28\nvar va_list args @ stack - 0x24\nvar const char *var_11h @ stack - 0x11\nvar unsigned long var_ch @ stack - 0xc\nvar int32_t var_8h @ stack - 0x8\narg const char *s @ stack + 0x4\n[0x080483d0]> ps @ 0x8048638 @!2\n%d\nA few things to note: sscanf in the while loop takes an integer (“%d”), and the result is placed in var_8h, which is subsequently used to increment var_ch. As soon as var_ch equals 15 (0xf) we gain entry.\nOther than that however it may not be very obvious at first glance what exactly is going on here. So let’s start a debugging session to execute the function.\n$ rizin -d ./crackme0x04\n[0xf3666cd0]> aaa\n[0xf3666cd0]> dcu main # execute until start of `main`\n[0x08048509]> dr eip=sym.check # instruction pointer to start of `check`\nWe will want to pass our own strings to check, so let’s allocate some memory and write a string to it.\n[0x08048509]> dm+ 512 @ -1 # Allocate 512 bytes at anywhere (-1)\nra0=0xf7fbb000\n[0x08048509]> wz \"letmein\" @ 0xf7fbb000 # Write null-terminated string to our allocated memory\n[0x08048509]> *esp+4=0xf7fbb000 # store the address under `arg_4h` (stack + 0x04)\nThe password check completes if var_ch equals 15 (0xf) so let’s add a breakpoint that prints the value of var_ch. We are going to be putting the breakpoint at the comparison of var_ch and 0xf, try to find it using pdf @ sym.check.\n[0x08048508]> pdf @ sym.check # find `cmp dword [var_ch], 0xf` \n...\n[0x08048508]> db @ 0x080484d6 # set breakpoint\n[0x08048508]> dbc 'pxw 1 @ esp-0xc' @ 0x080484d6 # execute command on break\n[0x08048508]> dcr # execute until return\n0xffeefb00 0x000000ff . # l\n0xffeefb00 0x000000fe . # e\n0xffeefb00 0x000000fd . # t\n0xffeefb00 0x000000fc . # m\n0xffeefb00 0x000000fb . # e\n0xffeefb00 0x000000fa . # i\n0xffeefb00 0x000000f9 . # n\nPassword Incorrect!\nWe can see that each letter increments var_ch by 4. Remember that sscanf in check takes a number (%d) as input. And because we didn’t provide any numbers, odds are that ‘4’ was probably some leftover data that happend to sit at the location of var_ch. This was never overwritten because sscanf didn’t encounter any numbers.\nSo let’s try giving it a number as input.\n[0x08048508]> wz \"1234\" @ 0xf7fbb010\n[0x08048508]> *esp+4=0xf7fbb010\n[0x08048508]> dr eip=sym.check\n[0x08048508]> dcr\n0xffeefb00 0x00000001 . # 1\n0xffeefb00 0x00000003 . # 2\n0xffeefb00 0x00000006 . # 3\n0xffeefb00 0x0000000a . # 4\nPassword Incorrect!\nNow we see what the function check is actually supposed to do: it increments the counter by each digit encountered. Or in other words it computes the digit sum, which has to land on 15 at some point during the computation.\nAnd indeed, cleaning up the decompiled check makes this more obvious.\nvoid sym.check(char *s)\n{\n int32_t var_11h = 0;\n int32_t sum = 0;\n int32_t d;\n\n for(int i = 0; i < strlen(s); i++) {\n var_11h = s[i];\n sscanf(&var_11h, \"%d\", &d);\n sum += d;\n if(sum == 0xf) {\n printf(\"Password OK!\\n\");\n exit(0);\n }\n }\n printf(\"Password Incorrect!\\n\");\n return;\n}\n$ ./crackme0x04\nIOLI Crackme Level 0x04\nPassword: 12345\nPassword OK!\n\n$ ./crackme0x04\nIOLI Crackme Level 0x04\nPassword: 96\nPassword OK!\nUsing what we discovered when we entered non-digit characters we can get some other passwords to work as well.\n$ ./crackme0x04\nIOLI Crackme Level 0x04\nPassword: 5asdf\nPassword OK!\n\n$ ./crackme0x04\nIOLI Crackme Level 0x04\nPassword: 0this-will-not-increment1but-this-will:)\nPassword OK!", "crumbs": [ "Crackmes", - "113  IOLI 0x04" + "114  IOLI 0x04" ] }, { "objectID": "src/crackmes/ioli/ioli_0x05.html", "href": "src/crackmes/ioli/ioli_0x05.html", - "title": "114  IOLI 0x05", + "title": "115  IOLI 0x05", "section": "", "text": "This is the sixth crackme.\n$ rz-bin -z ./crackme0x05\n[Strings]\nnth paddr vaddr len size section type string \n---------------------------------------------------------------------------\n0 0x0000066b 0x0804866b 13 14 .rodata ascii Password OK!\\n\n1 0x00000679 0x08048679 20 21 .rodata ascii Password Incorrect!\\n\n2 0x0000068e 0x0804868e 24 25 .rodata ascii IOLI Crackme Level 0x05\\n\n3 0x000006a7 0x080486a7 10 11 .rodata ascii Password: \nNo interesting strings, so let’s analyze.\n$ rizin ./crackme0x05\n[0x080483d0]> aa\n[0x080483d0]> pdg @ main\n\n// WARNING: [rz-ghidra] Detected overlap for variable var_11h\n\nundefined4 main(void)\n{\n int32_t var_88h;\n int32_t var_7ch;\n \n sym.imp.printf(\"IOLI Crackme Level 0x05\\n\");\n sym.imp.printf(\"Password: \");\n sym.imp.scanf(0x80486b2, &var_7ch);\n sym.check((int32_t)&var_7ch);\n return 0;\n}\n\n[0x080483d0]> ps @ 0x80486b2\n%s\nWe can see the same structure is used again: a string is read by scanf and is passed to check.\n[0x080483d0]> pdg @ sym.check\n\n// WARNING: Variable defined which should be unmapped: var_28h\n// WARNING: Variable defined which should be unmapped: var_24h\n// WARNING: [rz-ghidra] Detected overlap for variable var_11h\n\nvoid sym.check(int32_t arg_4h)\n{\n uint32_t uVar1;\n int32_t var_28h;\n int32_t var_24h;\n undefined var_11h;\n int32_t var_10h;\n int32_t var_ch;\n int32_t var_8h;\n \n var_ch = 0;\n var_10h = 0;\n while( true ) {\n uVar1 = sym.imp.strlen(arg_4h);\n if (uVar1 <= (uint32_t)var_10h) break;\n var_11h = *(undefined *)(var_10h + arg_4h);\n sym.imp.sscanf(&var_11h, 0x8048668, &var_8h);\n var_ch = var_ch + var_8h;\n if (var_ch == 0x10) {\n sym.parell(arg_4h);\n }\n var_10h = var_10h + 1;\n }\n sym.imp.printf(\"Password Incorrect!\\n\");\n return;\n}\n\n[0x080483d0]> ps @ 0x8048668 @! 2\n%d\nWe can see that check is mostly the same, except that this time the digit sum has to equal 16 (0x10), after which a function named parell is called.\n[0x080483d0]> pdg @ sym.parell\n\n// WARNING: Variable defined which should be unmapped: var_18h\n// WARNING: Variable defined which should be unmapped: var_14h\n\nvoid sym.parell(int32_t arg_4h)\n{\n int32_t var_18h;\n int32_t var_14h;\n int32_t var_8h;\n \n sym.imp.sscanf(arg_4h, 0x8048668, &var_8h);\n if ((var_8h & 1U) == 0) {\n sym.imp.printf(\"Password OK!\\n\");\n sym.imp.exit(0);\n }\n return;\n}\n\n[0x080483d0]> ps @ 0x8048668 @! 2\n%d\nWe can see here that the function parell takes a string, converts it to an integer and performs a parity check on it (var_8h & 1U) == 0. In this case the least significant bit has to be 0, which means the number has to be even.\n$ ./crackme0x05\nIOLI Crackme Level 0x05\nPassword: 88\nPassword OK!\n\n$ ./crackme0x05\nIOLI Crackme Level 0x05\nPassword: 12346\nPassword OK!\nAnd our trick from the previous crackme works as well.\n$ ./crackme0x05\nIOLI Crackme Level 0x05\nPassword: 4asdf\nPassword OK!\n\n$ ./crackme0x05\nIOLI Crackme Level 0x05\nPassword: 0this-doesnt-count4this-does\nPassword OK!", "crumbs": [ "Crackmes", - "114  IOLI 0x05" + "115  IOLI 0x05" ] }, { "objectID": "src/crackmes/ioli/ioli_0x06.html", "href": "src/crackmes/ioli/ioli_0x06.html", - "title": "115  IOLI 0x06", + "title": "116  IOLI 0x06", "section": "", "text": "Onto the seventh crackme.\n$ rz-bin -z ./crackme0x06\n[Strings]\nnth paddr vaddr len size section type string \n---------------------------------------------------------------------------\n0 0x00000738 0x08048738 4 5 .rodata ascii LOLO\n1 0x00000740 0x08048740 13 14 .rodata ascii Password OK!\\n\n2 0x0000074e 0x0804874e 20 21 .rodata ascii Password Incorrect!\\n\n3 0x00000763 0x08048763 24 25 .rodata ascii IOLI Crackme Level 0x06\\n\n4 0x0000077c 0x0804877c 10 11 .rodata ascii Password: \nDoing our routine strings check we can see a new contender: LOLO.\n$ ./crackme0x06\nIOLI Crackme Level 0x06\nPassword: LOLO\nPassword Incorrect!\nNo dice, so let’s take a closer look.\n$ rizin ./crackme0x06\n[0x08048400]> aa\n[0x08048400]> pdg @ main\n\n// WARNING: [rz-ghidra] Detected overlap for variable var_11h\n\nundefined4 main(undefined4 placeholder_0, undefined4 placeholder_1, char **envp)\n{\n int32_t var_88h;\n int32_t var_7ch;\n \n sym.imp.printf(\"IOLI Crackme Level 0x06\\n\");\n sym.imp.printf(\"Password: \");\n sym.imp.scanf(0x8048787, &var_7ch);\n sym.check((int32_t)&var_7ch, (int32_t)envp);\n return 0;\n}\n\n[0x08048400]> ps @ 0x8048787\n%s\n[0x08048400]> afvl @ main\nvar int32_t var_88h @ stack - 0x88\nvar int32_t var_7ch @ stack - 0x7c\narg char **envp @ stack + 0xc\nThis looks the same as before, except the program’s environment variables envp are passed to check.\n[0x08048400]> pdg @ sym.check\n\n// WARNING: Variable defined which should be unmapped: var_28h\n// WARNING: Variable defined which should be unmapped: var_24h\n// WARNING: [rz-ghidra] Detected overlap for variable var_11h\n\nvoid sym.check(int32_t arg_4h, int32_t arg_8h)\n{\n uint32_t uVar1;\n int32_t var_28h;\n int32_t var_24h;\n undefined var_11h;\n int32_t var_10h;\n int32_t var_ch;\n int32_t var_8h;\n \n var_ch = 0;\n var_10h = 0;\n while( true ) {\n uVar1 = sym.imp.strlen(arg_4h);\n if (uVar1 <= (uint32_t)var_10h) break;\n var_11h = *(undefined *)(var_10h + arg_4h);\n sym.imp.sscanf(&var_11h, 0x804873d, &var_8h);\n var_ch = var_ch + var_8h;\n if (var_ch == 0x10) {\n sym.parell(arg_4h, arg_8h);\n }\n var_10h = var_10h + 1;\n }\n sym.imp.printf(\"Password Incorrect!\\n\");\n return;\n}\nThis looks mostly the same as well. If we follow envp (now named arg_8h) we can see it gets passed to parell.\n[0x08048400]> pdg @ sym.parell\n\n// WARNING: Variable defined which should be unmapped: var_18h\n// WARNING: Variable defined which should be unmapped: var_14h\n\nvoid sym.parell(int32_t arg_4h, int32_t arg_8h)\n{\n int32_t iVar1;\n int32_t var_18h;\n int32_t var_14h;\n int32_t var_ch;\n int32_t var_8h;\n \n sym.imp.sscanf(arg_4h, 0x804873d, &var_8h);\n iVar1 = sym.dummy(var_8h, arg_8h);\n if (iVar1 != 0) {\n for (var_ch = 0; var_ch < 10; var_ch = var_ch + 1) {\n if ((var_8h & 1U) == 0) {\n sym.imp.printf(\"Password OK!\\n\");\n sym.imp.exit(0);\n }\n }\n }\n return;\n}\nWe can see that the parity check is still in place, except it’s now in a loop that executes 10 times, but only if dummy() returns non-zero.\n[0x08048400]> pdg @ sym.dummy\n\n// WARNING: Variable defined which should be unmapped: var_18h\n// WARNING: Variable defined which should be unmapped: var_14h\n\nundefined4 sym.dummy(undefined4 placeholder_0, int32_t arg_8h)\n{\n int32_t iVar1;\n int32_t var_18h;\n int32_t var_14h;\n int32_t var_ch;\n int32_t var_8h;\n \n var_8h = 0;\n do {\n if (*(int32_t *)(var_8h * 4 + arg_8h) == 0) {\n return 0;\n }\n iVar1 = var_8h * 4;\n var_8h = var_8h + 1;\n iVar1 = sym.imp.strncmp(*(undefined4 *)(iVar1 + arg_8h), \"LOLO\", 3);\n } while (iVar1 != 0);\n return 1;\n}\nLiving up to its name, dummy does not use its first parameter at all, only the second one is used which is the envp parameter from main. Apparently some part of envp has to equal “LOL” (only the first 3 characters are used , note the ‘3’ in strncmp).\nIt will be easier to figure out how dummy works if we run the code, so let’s use the debugger again!\n$ rizin -d ./crackme0x06\n[0xf7fb1630]> aa\n[0xf7fb1630]> dcu sym.dummy\nContinue until 0x080484b4\nIOLI Crackme Level 0x06\nPassword: 88\nhit breakpoint at: 0x80484b4\nNow we should be at the start of dummy, let’s see where we can place a breakpoint.\n[0x080484b4]> pdf\n ; CALL XREF from sym.parell @ 0x8048547\n ;-- eip:\n/ sym.dummy(int32_t arg_8h);\n| ; var int32_t var_18h @ stack - 0x18\n| ; var int32_t var_14h @ stack - 0x14\n| ; var int32_t var_ch @ stack - 0xc\n| ; var int32_t var_8h @ stack - 0x8\n| ; arg int32_t arg_8h @ stack + 0x8\n| 0x080484b4 push ebp\n| 0x080484b5 mov ebp, esp\n| 0x080484b7 sub esp, 0x18\n| 0x080484ba mov dword [var_8h], 0\n| .-> 0x080484c1 mov eax, dword [var_8h]\n| : 0x080484c4 lea edx, [eax*4]\n| : 0x080484cb mov eax, dword [arg_8h]\n| : 0x080484ce cmp dword [edx + eax], 0\n| ,==< 0x080484d2 je 0x804850e\n| |: 0x080484d4 mov eax, dword [var_8h]\n| |: 0x080484d7 lea ecx, [eax*4]\n| |: 0x080484de mov edx, dword [arg_8h]\n| |: 0x080484e1 lea eax, [var_8h]\n| |: 0x080484e4 inc dword [eax]\n| |: 0x080484e6 mov dword [var_14h], 3\n| |: 0x080484ee mov dword [var_18h], 0x8048738 ; str.LOLO\n| |: ; [0x8048738:4]=0x4f4c4f4c ; \"LOLO\"\n| |: 0x080484f6 mov eax, dword [ecx + edx]\n| |: 0x080484f9 mov dword [esp], eax\n| |: 0x080484fc call sym.imp.strncmp ; sym.imp.strncmp ; int strncmp(const char *s1, const char *s2, size_t n)\n| |: 0x08048501 test eax, eax\n| |`=< 0x08048503 jne 0x80484c1\n| | 0x08048505 mov dword [var_ch], 1\n| |,=< 0x0804850c jmp 0x8048515\n| `--> 0x0804850e mov dword [var_ch], 0\n| | ; CODE XREF from sym.dummy @ 0x804850c\n| `-> 0x08048515 mov eax, dword [var_ch]\n| 0x08048518 leave\n\\ 0x08048519 ret\nThe instruction at 0x080484f9 looks like a good spot. This is just before strncmp is called, so we can see what value is passed to it.\n[0x08048502]> db @ 0x080484f9\n[0x08048502]> dbc 'psi @r:eax' @ 0x080484f9\n[0x08048502]> dcr\nPWD=/home/rizin\nHOME=/home/rizin\nUSER=rizin\nPATH=/usr/local/sbin:/usr/local/bin:/usr/bin\nSHELL=/usr/bin/sh\nRunning dcr you should be greeted with all the environment variables passed to the program. From this we can safely conclude that dummy is looking for an environment variable starting with “LOL”, so let’s try it.\nRemember that there are 3 constraints to the password now:\n\nDigit sum reaches 16 at some point\nThe number is even\nAn environment variable starting with “LOL” is set\n\n$ LOL= ./crackme0x06\nIOLI Crackme Level 0x06\nPassword: 88\nPassword OK!\n\n$ LOL= ./crackme0x06\nIOLI Crackme Level 0x06\nPassword: 12346\nPassword OK!", "crumbs": [ "Crackmes", - "115  IOLI 0x06" + "116  IOLI 0x06" ] }, { "objectID": "src/crackmes/ioli/ioli_0x07.html", "href": "src/crackmes/ioli/ioli_0x07.html", - "title": "116  IOLI 0x07", + "title": "117  IOLI 0x07", "section": "", - "text": "116.1 WTF?\nAlready onto the eighth crackme!\nDoing our routine strings check we see another new contender, wtf? Literally.\nUpping the difficulty, check is no longer exported so it’s now listed as fcn.080485b9. To make our lives a bit easier, let’s set the name manually.\nThis looks like the check we’ve seen in previous version except there is now a parity check slapped on the end of it where the string “wtf?” is printed.\nBefore we can continue to the other functions, they have to be analyzed first. We can analyze all functions recursively using afr.\nThe reason we’re doing it this way in this case, is because aaa will cause some critical information to be omitted: namely the code that prints \"wtf?\", more on that later.\nFor now though let’s first check out fcn.08048542. We can probably already guess its identity as the code structure remains largely unchanged from the previous versions. But it can’t hurt to do our due diligence.\nThat does indeed look like parell from the previous versions. And that must make fcn.080484b4 dummy. But look, there’s an extra if inside the parity check! Apparently some global variable has to be set to 1 in order for the password to be valid.\nAnd this must be dummy… With an addition. Can you spot it? This is where that global variable that we saw earlier gets set! On the line containing *(undefined4 *)0x804a02c = 1;, more specifically.\nBut before we continue let’s see if there are any other references to or from this global variable.\nIt doesn’t appear to be the case, so let’s go back to check.\nWe still have one unidentified function left: fcn.08048524.\nThis doesn’t seem to do much, other than to print that the password is incorrect and exit. So let’s call it print_and_exit.\nInterestingly, print_and_exit is called unconditionally before the second parity check, meaning it is never executed under normal circumstances. If we had used aaa to analyze this binary, Rizin would have noticed this, and it would have simply omitted it from the disassembly and decompilation outputs.\nIf you happen to accidentally (or intentionally) run aaa, you can remove all function analysis using af-*, after which you can run aa, followed by afr where needed.\nWith that being said, it doesn’t seem like the password constraints have changed at all from the previous versions:\nBefore we close Rizin however let’s save this as a project first, so we don’t lose all our hard work naming the functions.\nAnd as we concluded, the passwords from the previous version still work.\nWe could go to the next one. Technically we’ve solved this crackme. But we have some unfinished business: the wtf? string. Let’s see if we can find a way to reach the code that’s supposed to write it to the console!\nIt’s easy enough using the debugger: we can simply set the instruction pointer to some location after the print_and_exit function (remember dr eip=<address>).\nWe can reopen the current file in debug mode using the ood command. We do need an environment variable set that starts with LOL, we can achieve this using the dor command. And let’s also set a breakpoint at the location print_and_exit is called so we can jump over it manually.\nNow we should be at the instruction that reads call print_and_exit (confirm with pd 1 @ eip). Now we need to find the address of the instruction that comes after this one and set the instruction pointer to equal this value.\nWith the print_and_exit function skipped we can continue execution.\nWe’ve successfully triggered the wtf? code using the debugger. But that’s no fun! Let’s see if there is a way we can reach that code (semi-)naturally.\nIn order for the print_and_exit function to be called we have to fail parell or the digit sum check. Failing parell is tricky because the same version has to succeed after print_and_exit in order for our desired string to be printed. So we’ll have to fail the digit sum check, which means making sure that our digit sum will not land on 16 during the computation.\nEasy enough! The only problem we have is that exit stops the process… But what if we were to make our own version of exit?\nThis turns exit into something that, well, doesn’t exit. __builtin_return_address is used to look two call frames up for a return address (the return address of print_and_exit) and jumps to it. Let’s save it to a file called exit.c. Compile it to a shared library using gcc -m32 -shared -o libexit.so exit.c and then we can preload it using LD_PRELOAD.\nThere it is!\nNow that exit is a simple trampoline, something interesting happens when we enter a valid password.\n“Password OK!” No. “Password Incorrect!” wtf? indeed.", + "text": "117.1 WTF?\nAlready onto the eighth crackme!\nDoing our routine strings check we see another new contender, wtf? Literally.\nUpping the difficulty, check is no longer exported so it’s now listed as fcn.080485b9. To make our lives a bit easier, let’s set the name manually.\nThis looks like the check we’ve seen in previous version except there is now a parity check slapped on the end of it where the string “wtf?” is printed.\nBefore we can continue to the other functions, they have to be analyzed first. We can analyze all functions recursively using afr.\nThe reason we’re doing it this way in this case, is because aaa will cause some critical information to be omitted: namely the code that prints \"wtf?\", more on that later.\nFor now though let’s first check out fcn.08048542. We can probably already guess its identity as the code structure remains largely unchanged from the previous versions. But it can’t hurt to do our due diligence.\nThat does indeed look like parell from the previous versions. And that must make fcn.080484b4 dummy. But look, there’s an extra if inside the parity check! Apparently some global variable has to be set to 1 in order for the password to be valid.\nAnd this must be dummy… With an addition. Can you spot it? This is where that global variable that we saw earlier gets set! On the line containing *(undefined4 *)0x804a02c = 1;, more specifically.\nBut before we continue let’s see if there are any other references to or from this global variable.\nIt doesn’t appear to be the case, so let’s go back to check.\nWe still have one unidentified function left: fcn.08048524.\nThis doesn’t seem to do much, other than to print that the password is incorrect and exit. So let’s call it print_and_exit.\nInterestingly, print_and_exit is called unconditionally before the second parity check, meaning it is never executed under normal circumstances. If we had used aaa to analyze this binary, Rizin would have noticed this, and it would have simply omitted it from the disassembly and decompilation outputs.\nIf you happen to accidentally (or intentionally) run aaa, you can remove all function analysis using af-*, after which you can run aa, followed by afr where needed.\nWith that being said, it doesn’t seem like the password constraints have changed at all from the previous versions:\nBefore we close Rizin however let’s save this as a project first, so we don’t lose all our hard work naming the functions.\nAnd as we concluded, the passwords from the previous version still work.\nWe could go to the next one. Technically we’ve solved this crackme. But we have some unfinished business: the wtf? string. Let’s see if we can find a way to reach the code that’s supposed to write it to the console!\nIt’s easy enough using the debugger: we can simply set the instruction pointer to some location after the print_and_exit function (remember dr eip=<address>).\nWe can reopen the current file in debug mode using the ood command. We do need an environment variable set that starts with LOL, we can achieve this using the dor command. And let’s also set a breakpoint at the location print_and_exit is called so we can jump over it manually.\nNow we should be at the instruction that reads call print_and_exit (confirm with pd 1 @ eip). Now we need to find the address of the instruction that comes after this one and set the instruction pointer to equal this value.\nWith the print_and_exit function skipped we can continue execution.\nWe’ve successfully triggered the wtf? code using the debugger. But that’s no fun! Let’s see if there is a way we can reach that code (semi-)naturally.\nIn order for the print_and_exit function to be called we have to fail parell or the digit sum check. Failing parell is tricky because the same version has to succeed after print_and_exit in order for our desired string to be printed. So we’ll have to fail the digit sum check, which means making sure that our digit sum will not land on 16 during the computation.\nEasy enough! The only problem we have is that exit stops the process… But what if we were to make our own version of exit?\nThis turns exit into something that, well, doesn’t exit. __builtin_return_address is used to look two call frames up for a return address (the return address of print_and_exit) and jumps to it. Let’s save it to a file called exit.c. Compile it to a shared library using gcc -m32 -shared -o libexit.so exit.c and then we can preload it using LD_PRELOAD.\nThere it is!\nNow that exit is a simple trampoline, something interesting happens when we enter a valid password.\n“Password OK!” No. “Password Incorrect!” wtf? indeed.", "crumbs": [ "Crackmes", - "116  IOLI 0x07" + "117  IOLI 0x07" ] }, { "objectID": "src/crackmes/ioli/ioli_0x07.html#wtf", "href": "src/crackmes/ioli/ioli_0x07.html#wtf", - "title": "116  IOLI 0x07", + "title": "117  IOLI 0x07", "section": "", "text": "[0x08048400]> ood\nProcess with PID 191704 started...\n[0xf173fcd0]> dor setenv=LOL=O\n[0xf173fcd0]> pdf @ check\n# find 'call print_and_exit'\n[0xf173fcd0]> db @ 0x0804862a\n[0xf173fcd0]> dc # run the program\nIOLI Crackme Level 0x07\nPassword: 2\nhit breakpoint at: 0x804862a\n\n[0x0804862a]> pd 2 @ eip\n│ ;-- eip:\n│ 0x0804862a b call print_and_exit ; print_and_exit\n│ 0x0804862f mov eax, dword [arg_8h]\n[0x0804862a]> dr eip=0x0804862f\n[0x0804862a]> pd 1 @ eip\n│ ;-- eip:\n│ 0x0804862f mov eax, dword [arg_8h]\n\n[0x0804862a]> dc\nwtf?\n(191704) Process exited with status=0x0\n[0xf3608579]> doc # close the debugging session\n\n\n\nvoid exit(int status) {\n void *ret = __builtin_return_address(2);\n\n __asm__ __volatile__ (\n \"leave\\n\\t\"\n \"jmp *%0\\n\\t\"\n : \"+rm\" (ret)\n );\n}\n\n$ LD_PRELOAD=./libexit.so LOL= ./crackme0x07\nIOLI Crackme Level 0x07\nPassword: 2\nPassword Incorrect!\nwtf?\n\n\n$ LD_PRELOAD=./libexit.so LOL= ./crackme0x07\nIOLI Crackme Level 0x07\nPassword: 888\nPassword OK!\nPassword Incorrect!\nwtf?", "crumbs": [ "Crackmes", - "116  IOLI 0x07" + "117  IOLI 0x07" ] }, { "objectID": "src/crackmes/ioli/ioli_0x08.html", "href": "src/crackmes/ioli/ioli_0x08.html", - "title": "117  IOLI 0x08", + "title": "118  IOLI 0x08", "section": "", "text": "Time for the ninth crackme.\n$ rz-bin -z ./crackme0x08\n[Strings]\nnth paddr vaddr len size section type string \n---------------------------------------------------------------------------\n0 0x000007a8 0x080487a8 4 5 .rodata ascii LOLO\n1 0x000007ad 0x080487ad 20 21 .rodata ascii Password Incorrect!\\n\n2 0x000007c5 0x080487c5 13 14 .rodata ascii Password OK!\\n\n3 0x000007d3 0x080487d3 5 6 .rodata ascii wtf?\\n\n4 0x000007d9 0x080487d9 24 25 .rodata ascii IOLI Crackme Level 0x08\\n\n5 0x000007f2 0x080487f2 10 11 .rodata ascii Password: \nIt looks like no new strings have been added. Before we jump into analyzing however, let’s first see which functions have changed from the previous version. We can get a nice overview using rz-diff.\n$ rz-diff -t functions crackme0x07 crackme0x08\n.--------------------------------------------------------------------------------------------------------------------------.\n| name0 | size0 | addr0 | type | similarity | addr1 | size1 | name1 |\n)--------------------------------------------------------------------------------------------------------------------------(\n| fcn.08048360 | 23 | 0x08048360 | COMPLETE | 1.000000 | 0x08048360 | 23 | sym._init |\n| sym.imp.__libc_start_main | 6 | 0x08048388 | COMPLETE | 1.000000 | 0x08048388 | 6 | sym.imp.__libc_start_main |\n| sym.imp.scanf | 6 | 0x08048398 | COMPLETE | 1.000000 | 0x08048398 | 6 | sym.imp.scanf |\n| sym.imp.strlen | 6 | 0x080483a8 | COMPLETE | 1.000000 | 0x080483a8 | 6 | sym.imp.strlen |\n| sym.imp.printf | 6 | 0x080483b8 | COMPLETE | 1.000000 | 0x080483b8 | 6 | sym.imp.printf |\n| sym.imp.sscanf | 6 | 0x080483c8 | COMPLETE | 1.000000 | 0x080483c8 | 6 | sym.imp.sscanf |\n| sym.imp.strncmp | 6 | 0x080483d8 | COMPLETE | 1.000000 | 0x080483d8 | 6 | sym.imp.strncmp |\n| sym.imp.exit | 6 | 0x080483e8 | COMPLETE | 1.000000 | 0x080483e8 | 6 | sym.imp.exit |\n| fcn.08048424 | 33 | 0x08048424 | COMPLETE | 1.000000 | 0x08048424 | 33 | fcn.08048424 |\n| fcn.08048450 | 47 | 0x08048450 | COMPLETE | 1.000000 | 0x08048450 | 47 | sym.__do_global_dtors_aux |\n| fcn.08048480 | 50 | 0x08048480 | COMPLETE | 1.000000 | 0x08048480 | 50 | sym.frame_dummy |\n| fcn.080484b4 | 112 | 0x080484b4 | COMPLETE | 1.000000 | 0x080484b4 | 112 | sym.dummy |\n| fcn.08048524 | 30 | 0x08048524 | COMPLETE | 1.000000 | 0x08048524 | 30 | sym.che |\n| fcn.08048542 | 119 | 0x08048542 | COMPLETE | 1.000000 | 0x08048542 | 119 | sym.parell |\n| fcn.080485b9 | 118 | 0x080485b9 | COMPLETE | 1.000000 | 0x080485b9 | 118 | sym.check |\n| fcn.08048755 | 4 | 0x08048755 | COMPLETE | 1.000000 | 0x08048755 | 4 | sym.__i686.get_pc_thunk.bx |\n| fcn.08048760 | 35 | 0x08048760 | COMPLETE | 1.000000 | 0x08048760 | 35 | sym.__do_global_ctors_aux |\n| fcn.0804878d | 17 | 0x0804878d | COMPLETE | 1.000000 | 0x0804878d | 17 | fcn.0804878d |\n`--------------------------------------------------------------------------------------------------------------------------'\nLook at that! crackme0x08 is completely identical to crackme0x07! With one exception however, crackme0x08 adds the symbol names back. Or looking at it another way: crackme0x07 is the stripped version of crackme0x08.\nThat means we can solve it the exact same way we solved crackme0x07.\n$ LOL= ./crackme0x08\nIOLI Crackme Level 0x08\nPassword: 12346\nPassword OK!\n\n$ LOL= ./crackme0x08\nIOLI Crackme Level 0x08\nPassword: 88\nPassword OK!\nAnd our exit trampoline from the previous version still works as well.\n$ LD_PRELOAD=./libexit.so LOL= ./crackme0x08\nIOLI Crackme Level 0x08\nPassword: 2\nPassword Incorrect!\nwtf?\n\n$ LD_PRELOAD=./libexit.so LOL= ./crackme0x08\nIOLI Crackme Level 0x08\nPassword: 88\nPassword OK!\nPassword Incorrect!\nwtf?\nAnalyzing the binary, there is not much to discover that we didn’t already know. With the exception that print_and_exit is actually called che. And the mysterious global variable referenced in dummy is called LOL.", "crumbs": [ "Crackmes", - "117  IOLI 0x08" + "118  IOLI 0x08" ] }, { "objectID": "src/crackmes/ioli/ioli_0x09.html", "href": "src/crackmes/ioli/ioli_0x09.html", - "title": "118  IOLI 0x09", + "title": "119  IOLI 0x09", "section": "", "text": "And that brings us onto the last crackme.\nWe can also use rz-diff to check for string differences.\n$ rz-diff -t strings crackme0x08 crackme0x09\n--- crackme0x08\n+++ ./crackme0x09\n@@ -1,4 +1,4 @@\n-IOLI Crackme Level 0x08\n\n+IOLI Crackme Level 0x09\n\n Password Incorrect!\n\n Password OK!\n\n Password: \nThe only change is the version info (from 0x08 to 0x09). So let’s check for functions.\n$ rz-diff -t functions crackme0x08 ./crackme0x09\n.--------------------------------------------------------------------------------------------------------------------------.\n| name0 | size0 | addr0 | type | similarity | addr1 | size1 | name1 |\n)--------------------------------------------------------------------------------------------------------------------------(\n| sym._init | 23 | 0x08048360 | PARTIAL | 0.826087 | 0x08048388 | 23 | fcn.08048388 |\n| sym.imp.__libc_start_main | 6 | 0x08048388 | COMPLETE | 1.000000 | 0x080483b0 | 6 | sym.imp.__libc_start_main |\n| sym.imp.scanf | 6 | 0x08048398 | COMPLETE | 1.000000 | 0x080483c0 | 6 | sym.imp.scanf |\n| sym.imp.strlen | 6 | 0x080483a8 | COMPLETE | 1.000000 | 0x080483d0 | 6 | sym.imp.strlen |\n| sym.imp.printf | 6 | 0x080483b8 | COMPLETE | 1.000000 | 0x080483e0 | 6 | sym.imp.printf |\n| sym.imp.sscanf | 6 | 0x080483c8 | COMPLETE | 1.000000 | 0x080483f0 | 6 | sym.imp.sscanf |\n| sym.imp.strncmp | 6 | 0x080483d8 | COMPLETE | 1.000000 | 0x08048400 | 6 | sym.imp.strncmp |\n| sym.imp.exit | 6 | 0x080483e8 | COMPLETE | 1.000000 | 0x08048410 | 6 | sym.imp.exit |\n| fcn.08048424 | 33 | 0x08048424 | PARTIAL | 0.939394 | 0x08048444 | 33 | fcn.08048444 |\n| sym.__do_global_dtors_aux | 47 | 0x08048450 | COMPLETE | 1.000000 | 0x08048470 | 47 | fcn.08048470 |\n| sym.frame_dummy | 50 | 0x08048480 | PARTIAL | 0.940000 | 0x080484a0 | 50 | fcn.080484a0 |\n| sym.dummy | 112 | 0x080484b4 | PARTIAL | 0.554745 | 0x080484d4 | 137 | fcn.080484d4 |\n| sym.che | 30 | 0x08048524 | UNLIKE | 0.4773 | 0x0804855d | 44 | fcn.0804855d |\n| sym.parell | 119 | 0x08048542 | PARTIAL | 0.581560 | 0x08048589 | 141 | fcn.08048589 |\n| sym.check | 118 | 0x080485b9 | PARTIAL | 0.689394 | 0x08048616 | 132 | fcn.08048616 |\n| sym.__i686.get_pc_thunk.bx | 4 | 0x08048755 | COMPLETE | 1.000000 | 0x08048766 | 4 | fcn.08048766 |\n| sym.__do_global_ctors_aux | 35 | 0x08048760 | PARTIAL | 0.942857 | 0x080487f0 | 35 | fcn.080487f0 |\n| fcn.0804878d | 17 | 0x0804878d | PARTIAL | 0.823529 | 0x0804881d | 17 | fcn.0804881d |\n`--------------------------------------------------------------------------------------------------------------------------'\nWe can see that a few functions have been changed. So let’s check it out! We can also see that this version strips the symbol names again, but that should be no problem. We can easily identify them using the functions diff.\n$ rizin ./crackme0x09\n[0x08048420]> aa\n[0x08048420]> afr @ main # recursively analyze functions, starting from main\n[0x08048420]> afn check @ fcn.08048616\n[0x08048420]> afn parell @ fcn.08048589\n[0x08048420]> afn che @ fcn.0804855d\n[0x08048420]> afn dummy @ fcn.080484d4\n[0x08048420]> pdg @ main\n\n// WARNING: Variable defined which should be unmapped: var_8h\n// WARNING: [rz-ghidra] Detected overlap for variable var_15h\n\nundefined4 main(undefined4 placeholder_0, undefined4 placeholder_1, char **envp)\n{\n int32_t unaff_EBX;\n int32_t var_88h;\n int32_t var_7ch;\n int32_t var_8h;\n \n fcn.08048766();\n sym.imp.printf(unaff_EBX + 0x16c);\n sym.imp.printf(unaff_EBX + 0x185);\n sym.imp.scanf(unaff_EBX + 400, &var_7ch);\n check((int32_t)&var_7ch, (int32_t)envp);\n return 0;\n}\nLooking at main we can see some changes: a new function fcn.08048766 is introduced, and all string addresses have been replaced by offsets to some base address unaff_EBX.\nLooking at the functions diff we can see that fcn.08048766 is named __i686.get_pc_thunk.bx. This function is used in position-independent code to get the addresses of global constants (like string constants). Let’s see if we can find out to which strings these offsets resolve to, but let’s first give this new function a name.\n[0x08048420]> afn sym.__i686.get_pc_thunk.bx @ fcn.08048766\nTo compute the addresses we can use ESIL. But we need to initialize it first.\n[0x08048420]> s main\n[0x080486ee]> aei\n[0x080486ee]> aeip\n[0x080486ee]> aeim\nNow we can step through the function, and all pointer arithmetic will be simulated! Open the interactive view with v, and then we can step through using the s key to step in and S to step over (this also works when using the debugger).\n[0x080486ee]> v\n# opens visual mode\n# step through by pressing Shift+S until we hit the instruction\n# call instruction to printf()\nHaving landed at the call to printf we can now look at what the address in eax points to. Exit visual mode by pressing q.\n[0x080486ee]> ar eax\neax = 0x08048869\n[0x080486ee]> ps @ 0x08048869\nIOLI Crackme Level 0x09\nWe can add this as a comment if we want. This way we don’t have to keep doing this ESIL simulation if we forget what particular string was printed here.\n[0x080486ef]> CC \"IOLI Crackme Level 0x09\" @ eip\n[0x080486ef]> pd 1 @ eip\n│ ;-- eip:\n│ 0x08048722 call sym.imp.printf ; sym.imp.printf ; IOLI Crackme Level 0x09 ; int printf(const char *format)\nPerfect! Onto the next string. We can skip the call to printf with the aess command, and then perform two steps using aes 2.\n[0x080486ee]> aess\n[0x080486ee]> aes 2\n[0x080486ee]> ar eax\neax = 0x08048882\n[0x080486ee]> ps @ 0x08048882\nPassword:\nWe can continue this until we have identified all strings. Or until our curiosity is sated.\nEither way, nothing of note has been added or changed in this version, which means that the password constraints are still the same.\n$ LOL= ./crackme0x09\nIOLI Crackme Level 0x09\nPassword: 12346\nPassword OK!\n\n$ LOL= ./crackme0x09\nIOLI Crackme Level 0x09\nPassword: 888\nPassword OK!\n\n$ LD_PRELOAD=./libexit.so LOL= ./crackme0x09\nIOLI Crackme Level 0x09\nPassword: 2\nPassword Incorrect!\nwtf?\n\n$ LD_PRELOAD=./libexit.so LOL= ./crackme0x09\nIOLI Crackme Level 0x09\nPassword: 888\nPassword OK!\nPassword Incorrect!\nwtf?\nAnd that concludes the IOLI crackmes!", "crumbs": [ "Crackmes", - "118  IOLI 0x09" + "119  IOLI 0x09" ] }, { "objectID": "src/crackmes/avatao/01-reverse4/intro.html", "href": "src/crackmes/avatao/01-reverse4/intro.html", - "title": "119  Avatao R3v3rs3 4", + "title": "120  Avatao R3v3rs3 4", "section": "", "text": "After a few years of missing out on wargames at Hacktivity, this year I’ve finally found the time to begin, and almost finish (yeah, I’m quite embarrassed about that unfinished webhack :) ) one of them. There were 3 different games at the conf, and I’ve chosen the one that was provided by avatao. It consisted of 8 challenges, most of them being basic web hacking stuff, one sandbox escape, one simple buffer overflow exploitation, and there were two reverse engineering exercises too. You can find these challenges on https://platform.avatao.com.", "crumbs": [ "Crackmes", - "119  Avatao R3v3rs3 4" + "120  Avatao R3v3rs3 4" ] }, { "objectID": "src/crackmes/avatao/01-reverse4/rizin.html", "href": "src/crackmes/avatao/01-reverse4/rizin.html", - "title": "120  .rizin", + "title": "121  .rizin", "section": "", "text": "I’ve decided to solve the reversing challenges using rizin, a free and open source reverse engineering framework. I have first learned about rizin back in 2011. during a huge project, where I had to reverse a massive, 11MB statically linked ELF. I simply needed something that I could easily patch Linux ELFs with. Granted, back then I’ve used rizin alongside IDA, and only for smaller tasks, but I loved the whole concept at first sight. Since then, rizin evolved a lot, and I was planning for some time now to solve some crackmes with the framework, and write writeups about them. Well, this CTF gave me the perfect opportunity :)\nBecause this writeup aims to show some of rizin’s features besides how the crackmes can be solved, I will explain every rizin command I use in blockquote paragraphs like this one:\n\nrizin tip: Always use ? or -h to get more information!\n\nIf you know rizin, and just interested in the crackme, feel free to skip those parts! Also keep in mind please, that because of this tutorial style I’m going to do a lot of stuff that you just don’t do during a CTF, because there is no time for proper bookkeeping (e.g. flag every memory area according to its purpose), and with such small executables you can succeed without doing these stuff.\nA few advice if you are interested in learning rizin (and frankly, if you are into RE, you should be interested in learning rizin :) ):\nThe framework has a lot of supplementary executables and a vast amount of functionality - and they are very well documented. I encourage you to read the available docs, and use the built-in help (by appending a ? to any command) extensively! E.g.:\n[0x00000000]> ?\nUsage: [.][times][cmd][~grep][@[@iter]addr!size][|>pipe] ; ...\nAppend '?' to any char command to get detailed help\nPrefix with number to repeat command N times (f.ex: 3x)\n|%var =valueAlias for 'env' command\n| *off[=[0x]value] Pointer read/write data/values (see ?v, wx, wv)\n| (macro arg0 arg1) Manage scripting macros\n| .[-|(m)|f|!sh|cmd] Define macro or load rizin, cparse or rlang file\n| = [cmd] Run this command via rap://\n| / Search for bytes, regexps, patterns, ..\n| ! [cmd] Run given command as in system(3)\n| # [algo] [len] Calculate hash checksum of current block\n| #!lang [..] Hashbang to run an rlang script\n| a Perform analysis of code\n| b Get or change block size\n\n...\n\n[0x00000000]> a?\n|Usage: a[abdefFghoprxstc] [...]\n| ab [hexpairs] analyze bytes\n| aa analyze all (fcns + bbs) (aa0 to avoid sub renaming)\n| ac [cycles] analyze which op could be executed in [cycles]\n| ad analyze data trampoline (wip)\n| ad [from] [to] analyze data pointers to (from-to)\n| ae [expr] analyze opcode eval expression (see ao)\n| af[rnbcsl?+-*] analyze Functions\n| aF same as above, but using analysis.depth=1\n\n...\nAlso, the project is under heavy development, there is no day without commits to the GitHub repo. So, as the readme says, you should always use the git version!\nSome highly recommended reading materials:\n\nRizin Book\nRizin Blog", "crumbs": [ "Crackmes", - "120  .rizin" + "121  .rizin" ] }, { "objectID": "src/crackmes/avatao/01-reverse4/first_steps.html", "href": "src/crackmes/avatao/01-reverse4/first_steps.html", - "title": "121  .first_steps", + "title": "122  .first_steps", "section": "", "text": "OK, enough of praising rizin, lets start reversing this stuff. First, you have to know your enemy:\n[0x00 avatao]$ rz-bin -I reverse4\npic false\ncanary true\nnx true\ncrypto false\nva true\nintrp /lib64/ld-linux-x86-64.so.2\nbintype elf\nclass ELF64\nlang c\narch x86\nbits 64\nmachine AMD x86-64 architecture\nos linux\nsubsys linux\nendian little\nstripped true\nstatic false\nlinenum false\nlsyms false\nrelocs false\nrpath NONE\nbinsz 8620\n\nrizin tip: rz-bin is one of the handy tools that comes with rizin. It can be used to extract information (imports, symbols, libraries, etc.) about binary executables. As always, check the help (rz-bin -h)!\n\nSo, it’s a dynamically linked, stripped, 64bit Linux executable - nothing fancy here. Let’s try to run it:\n[0x00 avatao]$ ./reverse4\n?\nSize of data: 2623\npamparam\nWrong!\n\n[0x00 avatao]$ \"\\x01\\x00\\x00\\x00\" | ./reverse4\nSize of data: 1\nOK, so it reads a number as a size from the standard input first, than reads further, probably “size” bytes/characters, processes this input, and outputs either “Wrong!”, nothing or something else, presumably our flag. But do not waste any more time monkeyfuzzing the executable, let’s fire up rizin, because in asm we trust!\n[0x00 avatao]$ rizin -A reverse4\n -- Heisenbug: A bug that disappears or alters its behavior when one attempts to probe or isolate it.\n[0x00400720]>\n\nrizin tip: The -A switch runs aaa command at start to analyze all referenced code, so we will have functions, strings, XREFS, etc. right at the beginning. As usual, you can get help with ?.\n\nIt is a good practice to create a project, so we can save our progress, and we can come back at a later time:\n[0x00400720]> Ps avatao_reverse4\navatao_reverse4\n[0x00400720]>\n\nrizin tip: You can save a project using Ps [file], and load one using Po [file]. With the -p option, you can load a project when starting rizin.\n\nWe can list all the strings rizin found:\n[0x00400720]> fs strings\n[0x00400720]> f\n0x00400e98 7 str.Wrong_\n0x00400e9f 27 str.We_are_in_the_outer_space_\n0x00400f80 18 str.Size_of_data:__u_n\n0x00400f92 23 str.Such_VM__MuCH_reV3rse_\n0x00400fa9 16 str.Use_everything_\n0x00400fbb 9 str.flag.txt\n0x00400fc7 26 str.You_won__The_flag_is:__s_n\n0x00400fe1 21 str.Your_getting_closer_\n[0x00400720]>\n\nrizin tip: rizin puts so-called flags on important/interesting offsets, and organizes these flags into flagspaces (strings, functions, symbols, etc.) You can list all flagspaces using fs, and switch the current one using fs [flagspace] (the default is *, which means all the flagspaces). The command f prints all flags from the currently selected flagspace(s).\n\nOK, the strings looks interesting, especially the one at 0x00400f92. It seems to hint that this crackme is based on a virtual machine. Keep that in mind!\nThese strings could be a good starting point if we were talking about a real-life application with many-many features. But we are talking about a crackme, and they tend to be small and simple, and focused around the problem to be solved. So I usually just take a look at the entry point(s) and see if I can figure out something from there. Nevertheless, I’ll show you how to find where these strings are used:\n[0x00400720]> axt @@=`f~[0]`\nd 0x400cb5 mov edi, str.Size_of_data:__u_n\nd 0x400d1d mov esi, str.Such_VM__MuCH_reV3rse_\nd 0x400d4d mov edi, str.Use_everything_\nd 0x400d85 mov edi, str.flag.txt\nd 0x400db4 mov edi, str.You_won__The_flag_is:__s_n\nd 0x400dd2 mov edi, str.Your_getting_closer_\n\nrizin tip: We can list cross-references to addresses using the axt [addr] command (similarly, we can use axf to list references from the address). The *@@* is an iterator, it just runs the command once for every arguments listed.\nThe argument list in this case comes from the command f[0]. It lists the strings from the executable with f, and uses the internal grep command to select only the first column ([0]) that contains the strings’ addresses.", "crumbs": [ "Crackmes", - "121  .first_steps" + "122  .first_steps" ] }, { "objectID": "src/crackmes/avatao/01-reverse4/main.html", "href": "src/crackmes/avatao/01-reverse4/main.html", - "title": "122  .main", + "title": "123  .main", "section": "", "text": "As I was saying, I usually take a look at the entry point, so let’s just do that:\n[0x00400720]> s main\n[0x00400c63]>\n\nrizin tip: You can go to any offset, flag, expression, etc. in the executable using the s command (seek). You can use references, like $$ (current offset), you can undo (s-) or redo (s+) seeks, search strings (s/ [string]) or hex values (s/x 4142), and a lot of other useful stuff. Make sure to check out s?!\n\nNow that we are at the beginning of the main function, we could use p to show a disassembly (pd, pdf), but rizin can do something much cooler: it has a visual mode, and it can display graphs similar to IDA, but way cooler, since they are ASCII-art graphs :)\n\nrizin tip: The command family p is used to print stuff. For example it can show disassembly (pd), disassembly of the current function (pdf), print strings (ps), hexdump (px), base64 encode/decode data (p6e, p6d), or print raw bytes (pr) so you can for example dump parts of the binary to other files. There are many more functionalities, check ?!\n\nR2 also has a minimap view which is incredibly useful for getting an overall look at a function:\n\n\n\nmain functions’s minimap\n\n\n\nrizin tip: With command V you can enter the so-called visual mode, which has several views. You can switch between them using p and P. The graph view can be displayed by hitting V in visual mode (or using VV at the prompt).\nHitting p in graph view will bring up the minimap. It displays the basic blocks and the connections between them in the current function, and it also shows the disassembly of the currently selected block (marked with @@@@@ on the minimap). You can select the next or the previous block using the *<TAB>* and the *<SHIFT><TAB>* keys respectively. You can also select the true or the false branches using the t and the f keys.\nIt is possible to bring up the prompt in visual mode using the : key, and you can use o to seek.\n\nLet’s read main node-by-node! The first block looks like this:\n\n\n\nmain bb-0c63\n\n\nWe can see that the program reads a word (2 bytes) into the local variable named local_10_6, and then compares it to 0xbb8. That’s 3000 in decimal:\n[0x00400c63]> % 0xbb8\nint32 3000\nuint32 3000\nhex 0xbb8\noctal 05670\nunit 2.9K\nsegment 0000:0bb8\nstring \"\\xb8\\v\"\nfvalue 3000.0\nfloat 3000.000000f\ndouble 3000.000000\nbinary 0b0000101110111000\ntrits 0t11010010\n\nrizin tip: yep, % will evaluate expressions, and print the result in various formats.\n\nIf the value is greater than 3000, then it will be forced to be 3000:\n\n\n\nmain bb-0ca6\n\n\nThere are a few things happening in the next block:\n\n\n\nmain bb-0cac\n\n\nFirst, the “Size of data:” message we saw when we run the program is printed. So now we know that the local variable local_10_6 is the size of the input data - so lets name it accordingly (remember, you can open the rizin shell from visual mode using the : key!):\n:> afvn local_10_6 input_size\n\nrizin tip: The af command family is used to analyze functions. This includes manipulating arguments and local variables too, which is accessible via the afv commands. You can list function arguments (afa), local variables (afv), or you can even rename them (afan, afvn). Of course there are lots of other features too - as usual: use the “?”, Luke!\n\nAfter this an input_size bytes long memory chunk is allocated, and filled with data from the standard input. The address of this memory chunk is stored in local_10 - time to use afvn again:\n:> afvn local_10 input_data\nWe’ve almost finished with this block, there are only two things remained. First, an 512 (0x200) bytes memory chunk is zeroed out at offset 0x00602120. A quick glance at XREFS to this address reveals that this memory is indeed used somewhere in the application:\n:> axt 0x00602120\nd 0x400cfe mov edi, 0x602120\nd 0x400d22 mov edi, 0x602120\nd 0x400dde mov edi, 0x602120\nd 0x400a51 mov qword [rbp - 8], 0x602120\nSince it probably will be important later on, we should label it:\n:> f sym.memory 0x200 0x602120\n\nrizin tip: Flags can be managed using the f command family. We’ve just added the flag sym.memory to a 0x200 bytes long memory area at 0x602120. It is also possible to remove (f-name), rename (fr [old] [new]), add comment (fC [name] [cmt]) or even color (fc [name] [color]) flags.\n\nWhile we are here, we should also declare that memory chunk as data, so it will show up as a hexdump in disassembly view:\n:> Cd 0x200 @ sym.memory\n\nrizin tip: The command family C is used to manage metadata. You can set (CC) or edit (CC) comments, declare memory areas as data (Cd), strings (Cs), etc. These commands can also be issued via a menu in visual mode invoked by pressing d.\n\nThe only remaining thing in this block is a function call to 0x400a45 with the input data as an argument. The function’s return value is compared to “*“, and a conditional jump is executed depending on the result.\nEarlier I told you that this crackme is probably based on a virtual machine. Well, with that information in mind, one can guess that this function will be the VM’s main loop, and the input data is the instructions the VM will execute. Based on this hunch, I’ve named this function vmloop, and renamed input_data to bytecode and input_size to bytecode_length. This is not really necessary in a small project like this, but it’s a good practice to name stuff according to their purpose (just like when you are writing programs).\n:> af vmloop 0x400a45\n:> afvn input_size bytecode_length\n:> afvn input_data bytecode\n\nrizin tip: The af command is used to analyze a function with a given name at the given address. The other two commands should be familiar from earlier.\n\nAfter renaming local variables, flagging that memory area, and renaming the VM loop function the disassembly looks like this:\n\n\n\nmain bb-0cac_meta\n\n\nSo, back to that conditional jump. If vmloop returns anything else than “*“, the program just exits without giving us our flag. Obviously we don’t want that, so we follow the false branch.\n\n\n\nmain bb-0d1d\n\n\nNow we see that a string in that 512 bytes memory area (sym.memory) gets compared to “Such VM! MuCH reV3rse!”. If they are not equal, the program prints the bytecode, and exits:\n\n\n\nmain bb-0dde\n\n\nOK, so now we know that we have to supply a bytecode that will generate that string when executed. As we can see on the minimap, there are still a few more branches ahead, which probably means more conditions to meet. Let’s investigate them before we delve into vmloop!\nIf you take a look at the minimap of the whole function, you can probably recognize that there is some kind of loop starting at block [0d34], and it involves the following nodes:\n\n[0d34]\n[0d65]\n[0d3d]\n[0d61]\n\nHere are the assembly listings for those blocks. The first one puts 0 into local variable local_10_4:\n\n\n\nmain bb-0d34\n\n\nAnd this one compares local_10_4 to 8, and executing a conditional jump based on the result:\n\n\n\nmain bb-0d65\n\n\nIt’s pretty obvious that local_10_4 is the loop counter, so lets name it accordingly:\n:> afvn local_10_4 i\nNext block is the actual loop body:\n\n\n\nmain bb-0d3d\n\n\nThe memory area at 0x6020e0 is treated as an array of dwords (4 byte values), and checked if the ith value of it is zero. If it is not, the loop simply continues:\n\n\n\nmain bb-0d61\n\n\nIf the value is zero, the loop breaks and this block is executed before exiting:\n\n\n\nmain bb-0d4d\n\n\nIt prints the following message: Use everything!” As we’ve established earlier, we are dealing with a virtual machine. In that context, this message probably means that we have to use every available instructions. Whether we executed an instruction or not is stored at 0x6020e0 - so lets flag that memory area:\n:> f sym.instr_dirty 4*9 0x6020e0\nAssuming we don’t break out and the loop completes, we are moving on to some more checks:\n\n\n\nmain bb-0d6b\n\n\nThis piece of code may look a bit strange if you are not familiar with x86_64 specific stuff. In particular, we are talking about RIP-relative addressing, where offsets are described as displacements from the current instruction pointer, which makes implementing PIE easier. Anyway, rizin is nice enough to display the actual address (0x602104). Got the address, flag it!\n:> f sym.good_if_ne_zero 4 0x602104\nKeep in mind though, that if RIP-relative addressing is used, flags won’t appear directly in the disassembly, but rizin displays them as comments:\n\n\n\nmain bb-0d6b_meta\n\n\nIf sym.good_if_ne_zero is zero, we get a message (“Your getting closer!”), and then the program exits. If it is non-zero, we move to the last check:\n\n\n\nmain bb-0d75\n\n\nHere the program compares a dword at 0x6020f0 (again, RIP-relative addressing) to 9. If its greater than 9, we get the same “Your getting closer!” message, but if it’s lesser, or equal to 9, we finally reach our destination, and get the flag:\n\n\n\nmain bb-0d80\n\n\nAs usual, we should flag 0x6020f0:\n:> f sym.good_if_le_9 4 0x6020f0\nWell, it seems that we have fully reversed the main function. To summarize it: the program reads a bytecode from the standard input, and feeds it to a virtual machine. After VM execution, the program’s state have to satisfy these conditions in order to reach the goodboy code:\n\nvmloop’s return value has to be “*”\nsym.memory has to contain the string “Such VM! MuCH reV3rse!”\nall 9 elements of sym.instr_dirty array should not be zero (probably means that all instructions had to be used at least once)\nsym.good_if_ne_zero should not be zero\nsym.good_if_le_9 has to be lesser or equal to 9\n\nThis concludes our analysis of the main function, we can now move on to the VM itself.", "crumbs": [ "Crackmes", - "122  .main" + "123  .main" ] }, { "objectID": "src/crackmes/avatao/01-reverse4/vmloop.html", "href": "src/crackmes/avatao/01-reverse4/vmloop.html", - "title": "123  .vmloop", + "title": "124  .vmloop", "section": "", "text": "[offset]> fcn.vmloop\n\n\n\nvmloop bb-0a45\n\n\nWell, that seems disappointingly short, but no worries, we have plenty to reverse yet. The thing is that this function uses a jump table at 0x00400a74,\n\n\n\nvmloop bb-0a74\n\n\nand rizin can’t yet recognize jump tables (Issue 3201), so the analysis of this function is a bit incomplete. This means that we can’t really use the graph view now, so either we just use visual mode, or fix those basic blocks. The entire function is just 542 bytes long, so we certainly could reverse it without the aid of the graph mode, but since this writeup aims to include as much rizin wisdom as possible, I’m going to show you how to define basic blocks.\nFirst, lets analyze what we already have! First, rdi is put into local_3. Since the application is a 64bit Linux executable, we know that rdi is the first function argument (as you may have recognized, the automatic analysis of arguments and local variables was not entirely correct), and we also know that vmloop’s first argument is the bytecode. So let’s rename local_3:\n:> afvn local_3 bytecode\nNext, sym.memory is put into another local variable at rbp-8 that rizin did not recognize. So let’s define it!\n:> afv 8 memory qword\n\nrizin tip: The afv [idx] [name] [type] command is used to define local variable at [frame pointer - idx] with the name [name] and type [type]. You can also remove local variables using the afv- [idx] command.\n\nIn the next block, the program checks one byte of bytecode, and if it is 0, the function returns with 1.\n\n\n\nvmloop bb-0c4d\n\n\nIf that byte is not zero, the program subtracts 0x41 from it, and compares the result to 0x17. If it is above 0x17, we get the dreaded “Wrong!” message, and the function returns with 0. This basically means that valid bytecodes are ASCII characters in the range of “A” (0x41) through “X” (0x41 + 0x17). If the bytecode is valid, we arrive at the code piece that uses the jump table:\n\n\n\nvmloop bb-0a74\n\n\nThe jump table’s base is at 0x400ec0, so lets define that memory area as a series of qwords:\n[0x00400a74]> s 0x00400ec0\n[0x00400ec0]> Cd 8 @@=`%s $$ $$+8*0x17 8`\n\nrizin tip: Except for the %s, all parts of this command should be familiar now, but lets recap it! Cd defines a memory area as data, and 8 is the size of that memory area. @@* is an iterator that make the preceding command run for every element that @@* holds. In this example it holds a series generated using the %s command. %s simply generates a series from the current seek (\\[*) to current seek + 8*0x17 (*\\]+80x17*) with a step of 8.\n\nThis is how the disassembly looks like after we add this metadata:\n[0x00400ec0]> pd 0x18\n ; DATA XREF from 0x00400a76 (unk)\n 0x00400ec0 .qword 0x0000000000400a80\n 0x00400ec8 .qword 0x0000000000400c04\n 0x00400ed0 .qword 0x0000000000400b6d\n 0x00400ed8 .qword 0x0000000000400b17\n 0x00400ee0 .qword 0x0000000000400c04\n 0x00400ee8 .qword 0x0000000000400c04\n 0x00400ef0 .qword 0x0000000000400c04\n 0x00400ef8 .qword 0x0000000000400c04\n 0x00400f00 .qword 0x0000000000400aec\n 0x00400f08 .qword 0x0000000000400bc1\n 0x00400f10 .qword 0x0000000000400c04\n 0x00400f18 .qword 0x0000000000400c04\n 0x00400f20 .qword 0x0000000000400c04\n 0x00400f28 .qword 0x0000000000400c04\n 0x00400f30 .qword 0x0000000000400c04\n 0x00400f38 .qword 0x0000000000400b42\n 0x00400f40 .qword 0x0000000000400c04\n 0x00400f48 .qword 0x0000000000400be5\n 0x00400f50 .qword 0x0000000000400ab6\n 0x00400f58 .qword 0x0000000000400c04\n 0x00400f60 .qword 0x0000000000400c04\n 0x00400f68 .qword 0x0000000000400c04\n 0x00400f70 .qword 0x0000000000400c04\n 0x00400f78 .qword 0x0000000000400b99\nAs we can see, the address 0x400c04 is used a lot, and besides that there are 9 different addresses. Let’s see that 0x400c04 first!\n\n\n\nvmloop bb-0c04\n\n\nWe get the message “Wrong!”, and the function just returns 0. This means that those are not valid instructions (they are valid bytecode though, they can be e.g. parameters!) We should flag 0x400c04 accordingly:\n[0x00400ec0]> f not_instr @ 0x0000000000400c04\nAs for the other offsets, they all seem to be doing something meaningful, so we can assume they belong to valid instructions. I’m going to flag them using the instructions’ ASCII values:\n[0x00400ec0]> f instr_A @ 0x0000000000400a80\n[0x00400ec0]> f instr_C @ 0x0000000000400b6d\n[0x00400ec0]> f instr_D @ 0x0000000000400b17\n[0x00400ec0]> f instr_I @ 0x0000000000400aec\n[0x00400ec0]> f instr_J @ 0x0000000000400bc1\n[0x00400ec0]> f instr_P @ 0x0000000000400b42\n[0x00400ec0]> f instr_R @ 0x0000000000400be5\n[0x00400ec0]> f instr_S @ 0x0000000000400ab6\n[0x00400ec0]> f instr_X @ 0x0000000000400b99\nOk, so these offsets were not on the graph, so it is time to define basic blocks for them!\n\nrizin tip: You can define basic blocks using the afb+ command. You have to supply what function the block belongs to, where does it start, and what is its size. If the block ends in a jump, you have to specify where does it jump too. If the jump is a conditional jump, the false branch’s destination address should be specified too.\n\nWe can get the start and end addresses of these basic blocks from the full disasm of vmloop.\n\n\n\nvmloop full\n\n\nAs I’ve mentioned previously, the function itself is pretty short, and easy to read, especially with our annotations. But a promise is a promise, so here is how we can create the missing basic blocks for the instructions:\n[0x00400ec0]> afb+ 0x00400a45 0x00400a80 0x00400ab6-0x00400a80 0x400c15\n[0x00400ec0]> afb+ 0x00400a45 0x00400ab6 0x00400aec-0x00400ab6 0x400c15\n[0x00400ec0]> afb+ 0x00400a45 0x00400aec 0x00400b17-0x00400aec 0x400c15\n[0x00400ec0]> afb+ 0x00400a45 0x00400b17 0x00400b42-0x00400b17 0x400c15\n[0x00400ec0]> afb+ 0x00400a45 0x00400b42 0x00400b6d-0x00400b42 0x400c15\n[0x00400ec0]> afb+ 0x00400a45 0x00400b6d 0x00400b99-0x00400b6d 0x400c15\n[0x00400ec0]> afb+ 0x00400a45 0x00400b99 0x00400bc1-0x00400b99 0x400c15\n[0x00400ec0]> afb+ 0x00400a45 0x00400bc1 0x00400be5-0x00400bc1 0x400c15\n[0x00400ec0]> afb+ 0x00400a45 0x00400be5 0x00400c04-0x00400be5 0x400c15\nIt is also apparent from the disassembly that besides the instructions there are three more basic blocks. Let’s create them too!\n[0x00400ec0]> afb+ 0x00400a45 0x00400c15 0x00400c2d-0x00400c15 0x400c3c 0x00400c2d\n[0x00400ec0]> afb+ 0x00400a45 0x00400c2d 0x00400c3c-0x00400c2d 0x400c4d 0x00400c3c\n[0x00400ec0]> afb+ 0x00400a45 0x00400c3c 0x00400c4d-0x00400c3c 0x400c61\nNote that the basic blocks starting at 0x00400c15 and 0x00400c2d ending in a conditional jump, so we had to set the false branch’s destination too!\nAnd here is the graph in its full glory after a bit of manual restructuring:\n\n\n\nvmloop graph\n\n\nI think it worth it, don’t you? :) (Well, the restructuring did not really worth it, because it is apparently not stored when you save the project.)\n\nrizin tip: You can move the selected node around in graph view using the HJKL keys.\n\nBy the way, here is how IDA’s graph of this same function looks like for comparison:\n\n\n\nIDA graph\n\n\nAs we browse through the disassembly of the instr_LETTER basic blocks, we should realize a few things. The first: all the instructions starts with a sequence like these:\n\n\n\nvmloop bb-0a80\n\n\n\n\n\nvmloop bb-0ab6\n\n\nIt became clear now that the 9 dwords at sym.instr_dirty are not simply indicators that an instruction got executed, but they are used to count how many times an instruction got called. Also, I should have realized earlier that sym.good_if_le_9 (0x6020f0) is part of this 9 dword array, but yeah, well, I didn’t, I have to live with it… Anyway, what the condition “sym.good_if_le_9 have to be lesser or equal 9” really means is that instr_P can not be executed more than 9 times:\n\n\n\nvmloop bb-0b42\n\n\nAnother similarity of the instructions is that 7 of them calls a function with either one or two parameters, where the parameters are the next, or the next two bytecodes. One parameter example:\n\n\n\nvmloop bb-0aec\n\n\nAnd a two parameters example:\n\n\n\nvmloop bb-0a80_full\n\n\nWe should also realize that these blocks put the number of bytes they eat up of the bytecode (1 byte instruction + 1 or 2 bytes arguments = 2 or 3) into a local variable at 0xc. rizin did not recognize this local var, so lets do it manually!\n:> afv 0xc instr_ptr_step dword\nIf we look at instr_J we can see that this is an exception to the above rule, since it puts the return value of the called function into instr_ptr_step instead of a constant 2 or 3:\n\n\n\nvmloop bb-0bc1\n\n\nAnd speaking of exceptions, here are the two instructions that do not call functions:\n\n\n\nvmloop bb-0be5\n\n\nThis one simply puts the next bytecode (the first the argument) into eax, and jumps to the end of vmloop. So this is the VM’s ret instruction, and we know that vmloop has to return “*”, so “R*” should be the last two bytes of our bytecode.\nThe next one that does not call a function:\n\n\n\nvmloop bb-0b6d\n\n\nThis is a one argument instruction, and it puts its argument to 0x6020c0. Flag that address!\n:> f sym.written_by_instr_C 4 @ 0x6020c0\nOh, and by the way, I do have a hunch that instr_C also had a function call in the original code, but it got inlined by the compiler. Anyway, so far we have these two instructions:\n\ninstr_R(a1): returns with a1\ninstr_C(a1): writes a1 to sym.written_by_instr_C\n\nAnd we also know that these accept one argument,\n\ninstr_I\ninstr_D\ninstr_P\ninstr_X\ninstr_J\n\nand these accept two:\n\ninstr_A\ninstr_S\n\nWhat remains is the reversing of the seven functions that are called by the instructions, and finally the construction of a valid bytecode that gives us the flag.\n###instr_A\nThe function this instruction calls is at offset 0x40080d, so lets seek there!\n[offset]> 0x40080d\n\nrizin tip: In visual mode you can just hit <Enter> when the current line is a jump or a call, and rizin will seek to the destination address.\n\nIf we seek to that address from the graph mode, we are presented with a message that says “Not in a function. Type ‘df’ to define it here. This is because the function is called from a basic block rizin did not recognize, so rizin could not find the function either. Lets obey, and type df! A function is indeed created, but we want some meaningful name for it. So press dr while still in visual mode, and name this function instr_A!\n\n\n\ninstr_A minimap\n\n\n\nrizin tip: You should realize that these commands are all part of the same menu system in visual mode I was talking about when we first used Cd to declare sym.memory as data.\n\nOk, now we have our shiny new fcn.instr_A, lets reverse it! We can see from the shape of the minimap that probably there is some kind cascading if-then-elif, or a switch-case statement involved in this function. This is one of the reasons the minimap is so useful: you can recognize some patterns at a glance, which can help you in your analysis (remember the easily recognizable for loop from a few paragraphs before?) So, the minimap is cool and useful, but I’ve just realized that I did not yet show you the full graph mode, so I’m going to do this using full graph. The first basic blocks:\n\n\n\ninstr_A bb-080d\n\n\nThe two function arguments (rdi and rsi) are stored in local variables, and the first is compared to 0. If it is, the function returns (you can see it on the minimap), otherwise the same check is executed on the second argument. The function returns from here too, if the argument is zero. Although this function is really tiny, I am going to stick with my methodology, and rename the local vars:\n:> afvn local_1 arg1\n:> afvn local_2 arg2\nAnd we have arrived to the predicted switch-case statement, and we can see that arg1’s value is checked against “M”, “P”, and “C”.\n\n\n\ninstr_A switch values\n\n\nThis is the “M” branch:\n\n\n\ninstr_A switch-M\n\n\nIt basically loads an address from offset 0x602088 and adds arg2 to the byte at that address. As rizin kindly shows us in a comment, 0x602088 initially holds the address of sym.memory, the area where we have to construct the “Such VM! MuCH reV3rse!” string. It is safe to assume that somehow we will be able to modify the value stored at 0x602088, so this “M” branch will be able to modify bytes other than the first. Based on this assumption, I’ll flag 0x602088 as sym.current_memory_ptr:\n:> f sym.current_memory_ptr 8 @ 0x602088\nMoving on to the “P” branch:\n\n\n\ninstr_A switch-P\n\n\nYes, this is the piece of code that allows us to modify sym.current_memory_ptr: it adds arg2 to it.\nFinally, the “C” branch:\n\n\n\ninstr_A switch-C\n\n\nWell, it turned out that instr_C is not the only instruction that modifies sym.written_by_instr_C: this piece of code adds arg2 to it.\nAnd that was instr_A, lets summarize it! Depending on the first argument, this instruction does the following:\n\narg1 == “M”: adds arg2 to the byte at sym.current_memory_ptr.\narg1 == “P”: steps sym.current_memory_ptr by arg2 bytes.\narg1 == “C”: adds arg2 to the value at sym.written_by_instr_C.\n\n###instr_S\nThis function is not recognized either, so we have to manually define it like we did with instr_A. After we do, and take a look at the minimap, scroll through the basic blocks, it is pretty obvious that these two functions are very-very similar. We can use rz-diff to see the difference.\n\nrizin tip: rz-diff is used to compare binary files. There’s a few options we can control the type of binary diffing the tool does, and to what kind of output format we want. One of the cool features is that it can generate DarumGrim-style bindiff graphs using the -g option.\n\nSince now we want to diff two functions from the same binary, we specify the offsets with -g, and use reverse4 for both binaries. Also, we create the graphs for comparing instr_A to instr_S and for comparing instr_S to instr_A.\n[0x00 ~]$ rz-diff -g 0x40080d,0x40089f reverse4 reverse4 | xdot -\n\n\n\ninstr_S graph1\n\n\n[0x00 ~]$ rz-diff -g 0x40089f,0x40080d reverse4 reverse4 | xdot -\n\n\n\ninstr_S graph2\n\n\nA sad truth reveals itself after a quick glance at these graphs: rz-diff is a liar! In theory, grey boxes should be identical, yellow ones should differ only at some offsets, and red ones should differ seriously. Well this is obviously not the case here - e.g. the larger grey boxes are clearly not identical. This is something I’m definitely going to take a deeper look at after I’ve finished this writeup.\nAnyway, after we get over the shock of being lied to, we can easily recognize that instr_S is basically a reverse-instr_A: where the latter does addition, the former does’ subtraction. To summarize this:\n\narg1 == “M”: subtracts arg2 from the byte at sym.current_memory_ptr.\narg1 == “P”: steps sym.current_memory_ptr backwards by arg2 bytes.\narg1 == “C”: subtracts arg2 from the value at sym.written_by_instr_C.\n\n###instr_I\n\n\n\ninstr_I\n\n\nThis one is simple, it just calls instr_A(arg1, 1). As you may have noticed the function call looks like call fcn.0040080d instead of call fcn.instr_A. This is because when you save and open a project, function names get lost - another thing to examine and patch in rizin!\n###instr_D\n\n\n\ninstr_D\n\n\nAgain, simple: it calls instr_S(arg1, 1).\n###instr_P\nIt’s local var rename time again!\n:> afvn local_0_1 const_M\n:> afvn local_0_2 const_P\n:> afvn local_3 arg1\n\n\n\ninstr_P\n\n\nThis function is pretty straightforward also, but there is one oddity: const_M is never used. I don’t know why it is there - maybe it is supposed to be some kind of distraction? Anyway, this function simply writes arg1 to sym.current_memory_ptr, and then calls instr_I(“P”). This basically means that instr_P is used to write one byte, and put the pointer to the next byte. So far this would seem the ideal instruction to construct most of the “Such VM! MuCH reV3rse!” string, but remember, this is also the one that can be used only 9 times!\n###instr_X\nAnother simple one, rename local vars anyway!\n:> afvn local_1 arg1\n\n\n\ninstr_X\n\n\nThis function XORs the value at sym.current_memory_ptr with arg1.\n###instr_J\nThis one is not as simple as the previous ones, but it’s not that complicated either. Since I’m obviously obsessed with variable renaming:\n:> afvn local_3 arg1\n:> afvn local_0_4 arg1_and_0x3f\n\n\n\ninstr_J\n\n\nAfter the result of arg1 & 0x3f is put into a local variable, arg1 & 0x40 is checked against 0. If it isn’t zero, arg1_and_0x3f is negated:\n\n\n\ninstr_J bb-09e1\n\n\nThe next branching: if arg1 >= 0, then the function returns arg1_and_0x3f,\n\n\n\ninstr_J bb-09e4\n\n\n\n\n\ninstr_J bb-0a1a\n\n\nelse the function branches again, based on the value of sym.written_by_instr_C:\n\n\n\ninstr_J bb-09ef\n\n\nIf it is zero, the function returns 2,\n\n\n\ninstr_J bb-0a13\n\n\nelse it is checked if arg1_and_0x3f is a negative number,\n\n\n\ninstr_J bb-09f9\n\n\nand if it is, sym.good_if_ne_zero is incremented by 1:\n\n\n\ninstr_J bb-09ff\n\n\nAfter all this, the function returns with arg1_and_0x3f:\n\n\n\ninstr_J bb-0a0e", "crumbs": [ "Crackmes", - "123  .vmloop" + "124  .vmloop" ] }, { "objectID": "src/crackmes/avatao/01-reverse4/instructionset.html", "href": "src/crackmes/avatao/01-reverse4/instructionset.html", - "title": "124  .instructionset", + "title": "125  .instructionset", "section": "", "text": "We’ve now reversed all the VM instructions, and have a full understanding about how it works. Here is the VM’s instruction set:\n\n\n\n\n\n\n\n\n\nInstruction\n1st arg\n2nd arg\nWhat does it do?\n\n\n\n\n“A”\n“M”\narg2\n*sym.current_memory_ptr += arg2\n\n\n\n“P”\narg2\nsym.current_memory_ptr += arg2\n\n\n\n“C”\narg2\nsym.written_by_instr_C += arg2\n\n\n“S”\n“M”\narg2\n*sym.current_memory_ptr -= arg2\n\n\n\n“P”\narg2\nsym.current_memory_ptr -= arg2\n\n\n\n“C”\narg2\nsym.written_by_instr_C -= arg2\n\n\n“I”\narg1\nn/a\ninstr_A(arg1, 1)\n\n\n“D”\narg1\nn/a\ninstr_S(arg1, 1)\n\n\n“P”\narg1\nn/a\n*sym.current_memory_ptr = arg1; instr_I(“P”)\n\n\n“X”\narg1\nn/a\n*sym.current_memory_ptr ^= arg1\n\n\n“J”\narg1\nn/a\narg1_and_0x3f = arg1 & 0x3f;if (arg1 & 0x40 != 0)  arg1_and_0x3f *= -1if (arg1 >= 0) return arg1_and_0x3f;else if (*sym.written_by_instr_C != 0) {  if (arg1_and_0x3f < 0)    ++*sym.good_if_ne_zero;  return arg1_and_0x3f;} else return 2;\n\n\n“C”\narg1\nn/a\n*sym.written_by_instr_C = arg1\n\n\n“R”\narg1\nn/a\nreturn(arg1)", "crumbs": [ "Crackmes", - "124  .instructionset" + "125  .instructionset" ] }, { "objectID": "src/crackmes/avatao/01-reverse4/bytecode.html", "href": "src/crackmes/avatao/01-reverse4/bytecode.html", - "title": "125  .bytecode", + "title": "126  .bytecode", "section": "", "text": "Well, we did the reverse engineering part, now we have to write a program for the VM with the instruction set described in the previous paragraph. Here is the program’s functional specification:\n\nthe program must return “*”\nsym.memory has to contain the string “Such VM! MuCH reV3rse!” after execution\nall 9 instructions have to be used at least once\nsym.good_if_ne_zero should not be zero\ninstr_P is not allowed to be used more than 9 times\n\nSince this document is about reversing, I’ll leave the programming part to the fellow reader :) But I’m not going to leave you empty-handed, I’ll give you one advice: Except for “J”, all of the instructions are simple, easy to use, and it should not be a problem to construct the “Such VM! MuCH reV3rse!” using them. “J” however is a bit complicated compared to the others. One should realize that its sole purpose is to make sym.good_if_ne_zero bigger than zero, which is a requirement to access the flag. In order to increment sym.good_if_ne_zero, three conditions should be met:\n\narg1 should be a negative number, otherwise we would return early\nsym.written_by_instr_C should not be 0 when “J” is called. This means that “C”, “AC”, or “SC” instructions should be used before calling “J”.\narg1_and_0x3f should be negative when checked. Since 0x3f’s sign bit is zero, no matter what arg1 is, the result of arg1 & 0x3f will always be non-negative. But remember that “J” negates arg1_and_0x3f if arg1 & 0x40 is not zero. This basically means that arg1’s 6th bit should be 1 (0x40 = 01000000b). Also, because arg1_and_0x3f can’t be 0 either, at least one of arg1’s 0th, 1st, 2nd, 3rd, 4th or 5th bits should be 1 (0x3f = 00111111b).\n\nI think this is enough information, you can go now and write that program. Or, you could just reverse engineer the quick’n’dirty one I’ve used during the CTF:\n\\x90\\x00PSAMuAP\\x01AMcAP\\x01AMhAP\\x01AM AP\\x01AMVAP\\x01AMMAP\\x01AM!AP\\x01AM AP\\x01AMMAP\\x01AMuAP\\x01AMCAP\\x01AMHAP\\x01AM AP\\x01AMrAP\\x01AMeAP\\x01AMVAP\\x01AM3AP\\x01AMrAP\\x01AMsAP\\x01AMeIPAM!X\\x00CAJ\\xc1SC\\x00DCR*\nKeep in mind though, that it was written on-the-fly, parallel to the reversing phase - for example there are parts that was written without the knowledge of all possible instructions. This means that the code is ugly and inefficient.", "crumbs": [ "Crackmes", - "125  .bytecode" + "126  .bytecode" ] }, { "objectID": "src/crackmes/avatao/01-reverse4/outro.html", "href": "src/crackmes/avatao/01-reverse4/outro.html", - "title": "126  .outro", + "title": "127  .outro", "section": "", "text": "Well, what can I say? Such VM, much reverse! :)\nWhat started out as a simple writeup for a simple crackme, became a rather lengthy writeup/rizin tutorial, so kudos if you’ve read through it. I hope you enjoyed it (I know I did), and maybe even learnt something from it. I’ve surely learnt a lot about rizin during the process, and I’ve even contributed some small patches, and got a few ideas of more possible improvements.", "crumbs": [ "Crackmes", - "126  .outro" + "127  .outro" ] }, { "objectID": "src/crackmes/hackthebox/intro.html", "href": "src/crackmes/hackthebox/intro.html", - "title": "127  hackthebox", + "title": "128  hackthebox", "section": "", "text": "The well-known hack the box hacking training platform offers reversing challenges.\nWe talk about of retired one solved with Rizin.", "crumbs": [ "Crackmes", - "127  hackthebox" + "128  hackthebox" ] }, { "objectID": "src/crackmes/hackthebox/find-the-easy-pass/intro.html", "href": "src/crackmes/hackthebox/find-the-easy-pass/intro.html", - "title": "128  Find The Easy Pass", + "title": "129  Find The Easy Pass", "section": "", "text": "This challenge implies to find the right password to win some points.\nWe present you a methodology to solve it with Rizin in particular by its built-in debugger on the Windows operating system.", "crumbs": [ "Crackmes", - "128  Find The Easy Pass" + "129  Find The Easy Pass" ] }, { "objectID": "src/crackmes/hackthebox/find-the-easy-pass/identification.html", "href": "src/crackmes/hackthebox/find-the-easy-pass/identification.html", - "title": "129  identification", + "title": "130  identification", "section": "", "text": "After un-compressing the challenge file Find The Easy Pass.zip, we can find a file named EasyPass.exe inside it.\nWe’re using rz-bin to identify the executable file.\nC:\\Users\\User\\Desktop\\htb>rz-bin -I EasyPass.exe\narch x86\nbaddr 0x400000\nbinsz 402432\nbintype pe\nbits 32\ncanary false\nretguard false\nclass PE32\ncmp.csum 0x00063785\ncompiled Fri Jun 19 15:22:17 1992\ncrypto false\nendian little\nhavecode true\nhdr.csum 0x00000000\nladdr 0x0\nlang c\nlinenum true\nlsyms true\nmachine i386\nmaxopsz 16\nminopsz 1\nnx false\nos windows\noverlay false\ncc cdecl\npcalign 0\npic false\nrelocs false\nsigned false\nsanitiz false\nstatic false\nstripped false\nsubsys Windows GUI\nva true\nThat’s interesting, EasyPass.exe is an x86 program, it’s a GUI program.\nNow, we will run the program to have some better idea on what it’s doing.\n\n\n\nidentification-run-program\n\n\nWe click on the Check Password\n\n\n\nidentification-error-message-printed\n\n\nInteresting, let’s search for Wrong Password! in the executable.\nC:\\Users\\User\\Desktop\\htb>rz-bin -iz EasyPass.exe | findstr /I Wrong\n\nC:\\Users\\User\\Desktop\\htb>\nWe’re unlucky but don’t panic, we will launch a more thorough research:\nC:\\Users\\User\\Desktop\\htb>rz-bin -izz EasyPass.exe | findstr /I Wrong\n5483 0x00053600 0x00454200 15 16 CODE ascii Wrong Password!\nThe “Wrong Password!” string is located at 0x00454200 in the CODE section.\n\nrizin tips: The first search (-iz) works on some flag spaces but not on the whole file, while the second command (-izz) is more exhaustive.", "crumbs": [ "Crackmes", - "129  identification" + "130  identification" ] }, { "objectID": "src/crackmes/hackthebox/find-the-easy-pass/find-the-validation-routine.html", "href": "src/crackmes/hackthebox/find-the-easy-pass/find-the-validation-routine.html", - "title": "130  Find the validation routine", + "title": "131  Find the validation routine", "section": "", "text": "The string “Wrong Password!” is located at 0x00454200 in the CODE section.\nIn this step, we wish to find the password, our approach will be to debug the program based on the information already collected.\nSpawned new process with pid 8556, tid = 8576\n= attach 8556 8576\nbin.baddr 0x00400000\nUsing 0x400000\nasm.bits 32\n\n[0x7ffeaa1c2630]> iz~Wrong\n[0x7ffeaa1c2630]> izz~Wrong\n5483 0x00053600 0x00454200 15 16 CODE ascii Wrong Password!\nrizin tips: We know where is located the “Wrong Password!” at 0x00454200 in the CODE section. To do the same research, we can use the iz and izz\n\n~ is Rizin’s built-in grep command which you can use to filter the output. Here, we’ve searched for the word “Wrong” in the strings of the data section.\nSeeking to 0x00454200- the location of the string:\n[0x7ffeaa1c2630]> s 0x00454200\n\n[0x00454200]> aaaa\nWe will ask Rizin to analyze the program with aaa.\n[0x00454200]> aaaa\n[x] Analyze all flags starting with sym. and entry0 (aa)\n[Warning: Invalid range. Use different search.in=? or analysis.in=dbg.maps.x\nWarning: Invalid range. Use different search.in=? or analysis.in=dbg.maps.x\n[x] Analyze function calls (aac)\n[x] Analyze len bytes of instructions for references (aar)\n[x] Check for classes\n[TOFIX: aaft can't run in debugger mode.ions (aaft)\n[x] Type matching analysis for all functions (aaft)\n[x] Propagate noreturn information\n[x] Use -AA or aaaa to perform additional experimental analysis.\n[Warning: Invalid range. Use different search.in=? or analysis.in=dbg.maps.x\n[x] Finding function preludes\n[x] Enable constraint types analysis for variables\n[0x00454200]> V\n\nrizin tips: The V command triggers the visual mode.\n\n\n\n\nfind-the-validation-routine-wrong-password\n\n\nPress p command to switch on the code view.\n\n\n\nfind-the-validation-routine-wrong-password-code-view\n\n\nPress x to display the cross-references.\n\n\n\nfind-the-validation-routine-wrong-password-xref\n\n\nPress enter or return to jump of this reference.\n\n\n\nfind-the-validation-routine-wrong-password-jump-to-xref\n\n\nRizin allows you to have a graph view by pressing the space bar.\n\n\n\nfind-the-validation-routine-wrong-password-graph-view-not-work\n\n\nFor the graph view to work here, Rizin needs the function to be analyzed. We will help by creating it from the beginning of the function where the string “Wrong Password!” is located.\nScroll up to the address 0x00454078.\n\n\n\nfind-the-validation-routine-wrong-password-prologue-function\n\n\nPress d and f to analyze the function.\n\n\n\nfind-the-validation-routine-wrong-password-analyze-function\n\n\nNow if you press the space bar the graph will be displayed.\n\n\n\nfind-the-validation-routine-wrong-password-graph-view\n\n\n\nrizin tips: to move around of graph, you can use the same keys like Vim: h, j, k, l.\n\n\n\n\nfind-the-validation-routine-wrong-password-interesting-code\n\n\nBy deduction, the address 0x00427a30 is the function which popup the messagebox.\nThe right node, print the “Wrong Password!”, the left one, probably prints the congratulations message.\nAt 0x00404628 is what which looks like a validation function because it is followed by a conditional test that either leads to the “Wrong Password!” message or the congratulation message.\nPress g and enter the address 0x004041dc to check if this one is the congratulation message.\n\n\n\nfind-the-validation-routine-wrong-jump-to-congrats\n\n\nPress n to ignore the create function message and press P.\n\n\n\nfind-the-validation-routine-congrats\n\n\nPress x and p.\n\n\n\nfind-the-validation-routine-congrats-node\n\n\nPress ; to enter a comment:\n\n\n\nfind-the-validation-routine-congrats-node-comment\n\n\n\n\n\nfind-the-validation-routine-congrats-node-comment-1\n\n\n\n\n\nfind-the-validation-routine-breakpoint-to-fish-code", "crumbs": [ "Crackmes", - "130  Find the validation routine" + "131  Find the validation routine" ] }, { "objectID": "src/crackmes/hackthebox/find-the-easy-pass/fire-up-the-debugger.html", "href": "src/crackmes/hackthebox/find-the-easy-pass/fire-up-the-debugger.html", - "title": "131  Fire up the debugger", + "title": "132  Fire up the debugger", "section": "", "text": "The next step will be to put a breakpoint at 0x0045412b, this address contains probably the right password or our. Press F2 key to put a breakpoint.\n\n\n\nfind-the-validation-routine-breakpoint-to-fish-code-1\n\n\nPress : , d and c to run EasyPass.exe.\n\n\n\nrun-the-program-debugged-1\n\n\n\n\n\nrun-the-program-debugged-2\n\n\nPress : , d and c or F9 key.\n\n\n\nrun-the-program-debugged-3\n\n\nPress : , d and c or F9 key.\n\n\n\nrun-the-program-debugged-4\n\n\nThe program is launched.\n\n\n\nrun-the-program-debugged-5\n\n\nEnter a placeholder text and click on the “Check Password” button.\nLogically, the program should stop at our breakpoint point.\n\n\n\nrun-the-program-debugged-6\n\n\nPress q and then p to show the debugger view panel.\n\n\n\nrun-the-program-debugged-7\n\n\nPress F8 key to step over.\n\n\n\nrun-the-program-debugged-8\n\n\nPress g, enter eax and P twice.\n\n\n\nrun-the-program-debugged-9\n\n\nThat’s great our placeholder text is in memory.\nPress p twice, g and enter rip.\n\n\n\nrun-the-program-debugged-10\n\n\nPress F8 key.\n\n\n\nrun-the-program-debugged-11\n\n\nPress g, enter edx and P twice.\n\n\n\nrun-the-program-debugged-12\n\n\nThe right password seems to be fortan!.\nPress p twice, g and enter rip.\nPress F8 key twice.\n\n\n\nrun-the-program-debugged-13\n\n\nThe call at 0x0045413d seems to compare the previous password and when unequal, the program jumps to the “Wrong Pasword!” message.\nPress F9 key to show the message box.\nAfter that, enter “fortan!” string and repeat the previous step until the address 0x0045413d.\n\n\n\nrun-the-program-debugged-14\n\n\nPress F8key twice.\n\n\n\nrun-the-program-debugged-15\n\n\nIt seems all right! Press F9 key to confirm this fact.\n\n\n\nrun-the-program-debugged-16", "crumbs": [ "Crackmes", - "131  Fire up the debugger" + "132  Fire up the debugger" ] }, { "objectID": "src/crackmes/hackthebox/find-the-easy-pass/bonus.html", "href": "src/crackmes/hackthebox/find-the-easy-pass/bonus.html", - "title": "132  Bonus", + "title": "133  Bonus", "section": "", "text": "In the previous pages, we found out the the right password. Now, we can figure out whether it is calculated at runtime or hard-coded into the binary.\nTo do this, we will look at what happens from the beginning of the current function from the address 0x00454084.\nAs a first, we’ll go to the address 0x00454084.\n\n\n\nbonus-01\n\n\nTake a break and observe the assembly code. You will see a repeating code sequence :\nmov eax, [ebp - X] ; or X is between 0x8 and 0x24\nmov edx, Y ; or Y is between 0x00454188 and 0x004541d0\nLook the address 0x00454188.\n\n\n\nbonus-02\n\n\n\n\n\nbonus-03\n\n\nPay attention to the previous picture. You can see the password broken down letter by letter.\nWe can see that the routine is concatenating each letter into a string and compares it to a user input.", "crumbs": [ "Crackmes", - "132  Bonus" + "133  Bonus" ] }, { "objectID": "src/refcard/intro.html", "href": "src/refcard/intro.html", - "title": "133  Rizin Reference Card", + "title": "134  Rizin Reference Card", "section": "", - "text": "133.1 Survival Guide\nThis chapter is based on the Radare 2 reference card by Thanat0s, which is under the GNU GPL. Original license is as follows:\nThose are the basic commands you will want to know and use for moving around a binary and getting information about it.", + "text": "134.1 Survival Guide\nThis chapter is based on the Radare 2 reference card by Thanat0s, which is under the GNU GPL. Original license is as follows:\nThose are the basic commands you will want to know and use for moving around a binary and getting information about it.", "crumbs": [ "Reference Card", - "133  Rizin Reference Card" + "134  Rizin Reference Card" ] }, { "objectID": "src/refcard/intro.html#survival-guide", "href": "src/refcard/intro.html#survival-guide", - "title": "133  Rizin Reference Card", + "title": "134  Rizin Reference Card", "section": "", "text": "Command\nDescription\n\n\n\n\nhelp\nFirst introduction\n\n\ns (tab)\nSeek to a different place\n\n\naa[a]\nAuto analyze (three a for more)\n\n\nafl\nList functions\n\n\nafvl\nList function local vars and args\n\n\navg\nList globals\n\n\nt\nList types\n\n\niz[z]\nList strings (two z for more)\n\n\npdf @ funcname\nDisassemble function (main, fcn, etc)\n\n\nx [nbytes]\nHexdump of nbytes, $b by default\n\n\nwx [nbytes]\nWrite hexadecimal string\n\n\naxt @ [flag/address]\nFind cross reference to a flag/address", "crumbs": [ "Reference Card", - "133  Rizin Reference Card" + "134  Rizin Reference Card" ] }, { "objectID": "src/refcard/intro.html#flags", "href": "src/refcard/intro.html#flags", - "title": "133  Rizin Reference Card", - "section": "133.2 Flags", - "text": "133.2 Flags\nFlags are like bookmarks, but they carry some extra information like size, tags or associated flagspace. Use f commands to list, set, get them.\n\n\n\nCommand\nDescription\n\n\n\n\nf name\nAdd flag “name”\n\n\nf- name\nRemove flag “name”\n\n\nfl\nList flags\n\n\nfd $$\nDescribe an offset\n\n\nfN [name]\nShow the real name\n\n\nfx [flagname]\nShow hexdump of flag\n\n\nfC [name] [comment]\nSet flag comment", + "title": "134  Rizin Reference Card", + "section": "134.2 Flags", + "text": "134.2 Flags\nFlags are like bookmarks, but they carry some extra information like size, tags or associated flagspace. Use f commands to list, set, get them.\n\n\n\nCommand\nDescription\n\n\n\n\nf name\nAdd flag “name”\n\n\nf- name\nRemove flag “name”\n\n\nfl\nList flags\n\n\nfd $$\nDescribe an offset\n\n\nfN [name]\nShow the real name\n\n\nfx [flagname]\nShow hexdump of flag\n\n\nfC [name] [comment]\nSet flag comment", "crumbs": [ "Reference Card", - "133  Rizin Reference Card" + "134  Rizin Reference Card" ] }, { "objectID": "src/refcard/intro.html#functions-and-variables", "href": "src/refcard/intro.html#functions-and-variables", - "title": "133  Rizin Reference Card", - "section": "133.3 Functions and variables", - "text": "133.3 Functions and variables\nFunctions appear after auto-analysis or after adding them manually with the af command.\n\n\n\nCommand\nDescription\n\n\n\n\naf\nAnalyze function\n\n\naf- name\nRemove function “name”\n\n\nafb\nList basic blocks\n\n\nafi\nShow function information\n\n\nafs\nShow function signature\n\n\nafvl\nShow function variables\n\n\nagf\nShow function graph", + "title": "134  Rizin Reference Card", + "section": "134.3 Functions and variables", + "text": "134.3 Functions and variables\nFunctions appear after auto-analysis or after adding them manually with the af command.\n\n\n\nCommand\nDescription\n\n\n\n\naf\nAnalyze function\n\n\naf- name\nRemove function “name”\n\n\nafb\nList basic blocks\n\n\nafi\nShow function information\n\n\nafs\nShow function signature\n\n\nafvl\nShow function variables\n\n\nagf\nShow function graph", "crumbs": [ "Reference Card", - "133  Rizin Reference Card" + "134  Rizin Reference Card" ] }, { "objectID": "src/refcard/intro.html#global-variables", "href": "src/refcard/intro.html#global-variables", - "title": "133  Rizin Reference Card", - "section": "133.4 Global variables", - "text": "133.4 Global variables\nGlobal variables appear after auto-analysis or after adding them manually.\n\n\n\nCommand\nDescription\n\n\n\n\navg\nShow all globals\n\n\navg name\nShow global “name”\n\n\navga name type\nAdd global variable\n\n\navgp name\nPrint global variable\n\n\navgx name\nShow xrefs to the global", + "title": "134  Rizin Reference Card", + "section": "134.4 Global variables", + "text": "134.4 Global variables\nGlobal variables appear after auto-analysis or after adding them manually.\n\n\n\nCommand\nDescription\n\n\n\n\navg\nShow all globals\n\n\navg name\nShow global “name”\n\n\navga name type\nAdd global variable\n\n\navgp name\nPrint global variable\n\n\navgx name\nShow xrefs to the global", "crumbs": [ "Reference Card", - "133  Rizin Reference Card" + "134  Rizin Reference Card" ] }, { "objectID": "src/refcard/intro.html#information", "href": "src/refcard/intro.html#information", - "title": "133  Rizin Reference Card", - "section": "133.5 Information", - "text": "133.5 Information\nBinary files have information stored inside the headers. The i command uses the RzBin API and allows us to the same things rz-bin does. Those are the most common ones.\n\n\n\nCommand\nDescription\n\n\n\n\nii\nInformation on imports\n\n\niI\nInfo on binary\n\n\nie\nDisplay entrypoint\n\n\niS\nDisplay sections\n\n\nir\nDisplay relocations", + "title": "134  Rizin Reference Card", + "section": "134.5 Information", + "text": "134.5 Information\nBinary files have information stored inside the headers. The i command uses the RzBin API and allows us to the same things rz-bin does. Those are the most common ones.\n\n\n\nCommand\nDescription\n\n\n\n\nii\nInformation on imports\n\n\niI\nInfo on binary\n\n\nie\nDisplay entrypoint\n\n\niS\nDisplay sections\n\n\nir\nDisplay relocations", "crumbs": [ "Reference Card", - "133  Rizin Reference Card" + "134  Rizin Reference Card" ] }, { "objectID": "src/refcard/intro.html#print-string", "href": "src/refcard/intro.html#print-string", - "title": "133  Rizin Reference Card", - "section": "133.6 Print string", - "text": "133.6 Print string\nThere are different ways to represent a string in memory. The ps command allows us to print it in UTF8, UTF-16, Pascal, zero-terminated, .. formats.\n\n\n\nCommand\nDescription\n\n\n\n\nps @ [offset]\nPrint auto-detected string\n\n\npsb @ [offset]\nPrint all strings in the current block\n\n\npsp @ [offset]\nPrint Pascal string\n\n\npsw @ [offset]\nPrint UTF-16 LE string\n\n\npsm @ [offset]\nPrint UTF-16 BE string\n\n\npsW @ [offset]\nPrint UTF-32 LE string\n\n\npsM @ [offset]\nPrint UTF-32 BE string", + "title": "134  Rizin Reference Card", + "section": "134.6 Print string", + "text": "134.6 Print string\nThere are different ways to represent a string in memory. The ps command allows us to print it in UTF8, UTF-16, Pascal, zero-terminated, .. formats.\n\n\n\nCommand\nDescription\n\n\n\n\nps @ [offset]\nPrint auto-detected string\n\n\npsb @ [offset]\nPrint all strings in the current block\n\n\npsp @ [offset]\nPrint Pascal string\n\n\npsw @ [offset]\nPrint UTF-16 LE string\n\n\npsm @ [offset]\nPrint UTF-16 BE string\n\n\npsW @ [offset]\nPrint UTF-32 LE string\n\n\npsM @ [offset]\nPrint UTF-32 BE string", "crumbs": [ "Reference Card", - "133  Rizin Reference Card" + "134  Rizin Reference Card" ] }, { "objectID": "src/refcard/intro.html#visual-mode", "href": "src/refcard/intro.html#visual-mode", - "title": "133  Rizin Reference Card", - "section": "133.7 Visual mode", - "text": "133.7 Visual mode\nThe visual mode is the standard interactive interface of rizin.\nTo enter in visual mode use the v or V command, and then you’ll only have to press keys to get the actions happen instead of commands.\n\n\n\nCommand\nDescription\n\n\n\n\nV\nEnter visual mode\n\n\np/P\nRotate modes (hex, disasm, debug, words, buf)\n\n\nc\nToggle (c)ursor\n\n\nq\nBack to rizin shell\n\n\nhjkl\nMove around (or HJKL) (left-down-up-right)\n\n\nEnter\nFollow address of jump/call\n\n\nsS\nStep/step over\n\n\no\nToggle asm.pseudo and asm.esil\n\n\n.\nSeek to program counter\n\n\n/\nIn cursor mode, search in current block\n\n\n:cmd\nRun rizin command\n\n\n;[-]cmt\nAdd/remove comment\n\n\n/*+-[]\nChange block size, [] = resize hex.cols\n\n\n<,>\nSeek aligned to block size\n\n\ni/a/A\n(i)nsert hex, (a)ssemble code, visual (A)ssembler\n\n\nb\nToggle breakpoint\n\n\nB\nBrowse evals, symbols, flags, classes, …\n\n\nd[f?]\nDefine function, data, code, ..\n\n\nD\nEnter visual diff mode (set diff.from/to)\n\n\ne\nEdit eval configuration variables\n\n\nf/F\nSet/unset flag\n\n\ngG\nGo seek to begin and end of file (0-$s)\n\n\nmK/’K\nMark/go to Key (any key)\n\n\nn/N\nSeek next/prev function/flag/hit (scr.nkey)\n\n\nC\nToggle (C)olors\n\n\nR\nRandomize color palette (ecr)\n\n\ntT\nTab related. see also tab\n\n\nv\nVisual code analysis menu\n\n\nV\n(V)iew graph (agv?)\n\n\nwW\nSeek cursor to next/prev word\n\n\nuU\nUndo/redo seek\n\n\nx\nShow xrefs of current func from/to data/code\n\n\nyY\nCopy and paste selection\n\n\nz\nfold/unfold comments in disassembly", + "title": "134  Rizin Reference Card", + "section": "134.7 Visual mode", + "text": "134.7 Visual mode\nThe visual mode is the standard interactive interface of rizin.\nTo enter in visual mode use the v or V command, and then you’ll only have to press keys to get the actions happen instead of commands.\n\n\n\nCommand\nDescription\n\n\n\n\nV\nEnter visual mode\n\n\np/P\nRotate modes (hex, disasm, debug, words, buf)\n\n\nc\nToggle (c)ursor\n\n\nq\nBack to rizin shell\n\n\nhjkl\nMove around (or HJKL) (left-down-up-right)\n\n\nEnter\nFollow address of jump/call\n\n\nsS\nStep/step over\n\n\no\nToggle asm.pseudo and asm.esil\n\n\n.\nSeek to program counter\n\n\n/\nIn cursor mode, search in current block\n\n\n:cmd\nRun rizin command\n\n\n;[-]cmt\nAdd/remove comment\n\n\n/*+-[]\nChange block size, [] = resize hex.cols\n\n\n<,>\nSeek aligned to block size\n\n\ni/a/A\n(i)nsert hex, (a)ssemble code, visual (A)ssembler\n\n\nb\nToggle breakpoint\n\n\nB\nBrowse evals, symbols, flags, classes, …\n\n\nd[f?]\nDefine function, data, code, ..\n\n\nD\nEnter visual diff mode (set diff.from/to)\n\n\ne\nEdit eval configuration variables\n\n\nf/F\nSet/unset flag\n\n\ngG\nGo seek to begin and end of file (0-$s)\n\n\nmK/’K\nMark/go to Key (any key)\n\n\nn/N\nSeek next/prev function/flag/hit (scr.nkey)\n\n\nC\nToggle (C)olors\n\n\nR\nRandomize color palette (ecr)\n\n\ntT\nTab related. see also tab\n\n\nv\nVisual code analysis menu\n\n\nV\n(V)iew graph (agv?)\n\n\nwW\nSeek cursor to next/prev word\n\n\nuU\nUndo/redo seek\n\n\nx\nShow xrefs of current func from/to data/code\n\n\nyY\nCopy and paste selection\n\n\nz\nfold/unfold comments in disassembly", "crumbs": [ "Reference Card", - "133  Rizin Reference Card" + "134  Rizin Reference Card" ] }, { "objectID": "src/refcard/intro.html#searching", "href": "src/refcard/intro.html#searching", - "title": "133  Rizin Reference Card", - "section": "133.8 Searching", - "text": "133.8 Searching\nThere are many situations where we need to find a value inside a binary or in some specific regions. Use the e search.in=? command to choose where the / command may search for the given value.\n\n\n\n\n\n\n\nCommand\nDescription\n\n\n\n\n/ foo\\00\nSearch for string ’foo\\0’\n\n\n/b\nSearch backwards\n\n\n//\nRepeat last search\n\n\n/w foo\nSearch for wide string ’f\\0o\\0o\\0’\n\n\n/wi foo\nSearch for wide string ignoring case\n\n\n/! ff\nSearch for first occurrence not matching\n\n\n/i foo\nSearch for string ’foo’ ignoring case\n\n\n/e /E.F/i\nMatch regular expression\n\n\n/x a1b2c3\nSearch for bytes; spaces and uppercase nibbles are allowed, same as /x A1 B2 C3\n\n\n/x a1..c3\nSearch for bytes ignoring some nibbles (auto-generates mask, in this example: ff00ff)\n\n\n/x a1b2:fff3\nSearch for bytes with mask (specify individual bits)\n\n\n/d 101112\nSearch for a deltified sequence of bytes\n\n\n/!x 00\nInverse hexa search (find first byte != 0x00)\n\n\n/c jmp [esp]\nSearch for asm code (see search.asmstr)\n\n\n/a jmp eax\nAssemble opcode and search its bytes\n\n\n/A\nSearch for AES expanded keys\n\n\n/r sym.printf\nAnalyze opcode reference an offset\n\n\n/R\nSearch for ROP gadgets\n\n\n/P\nShow offset of previous instruction\n\n\n/m magicfile\nSearch for matching magic file\n\n\n/p patternsize\nSearch for pattern of given size\n\n\n/z min max\nSearch for strings of given size\n\n\n/v[?248] num\nLook for a asm.bigendian 32bit value", + "title": "134  Rizin Reference Card", + "section": "134.8 Searching", + "text": "134.8 Searching\nThere are many situations where we need to find a value inside a binary or in some specific regions. Use the e search.in=? command to choose where the / command may search for the given value.\n\n\n\n\n\n\n\nCommand\nDescription\n\n\n\n\n/ foo\\00\nSearch for string ’foo\\0’\n\n\n/b\nSearch backwards\n\n\n//\nRepeat last search\n\n\n/w foo\nSearch for wide string ’f\\0o\\0o\\0’\n\n\n/wi foo\nSearch for wide string ignoring case\n\n\n/! ff\nSearch for first occurrence not matching\n\n\n/i foo\nSearch for string ’foo’ ignoring case\n\n\n/e /E.F/i\nMatch regular expression\n\n\n/x a1b2c3\nSearch for bytes; spaces and uppercase nibbles are allowed, same as /x A1 B2 C3\n\n\n/x a1..c3\nSearch for bytes ignoring some nibbles (auto-generates mask, in this example: ff00ff)\n\n\n/x a1b2:fff3\nSearch for bytes with mask (specify individual bits)\n\n\n/d 101112\nSearch for a deltified sequence of bytes\n\n\n/!x 00\nInverse hexa search (find first byte != 0x00)\n\n\n/c jmp [esp]\nSearch for asm code (see search.asmstr)\n\n\n/a jmp eax\nAssemble opcode and search its bytes\n\n\n/A\nSearch for AES expanded keys\n\n\n/r sym.printf\nAnalyze opcode reference an offset\n\n\n/R\nSearch for ROP gadgets\n\n\n/P\nShow offset of previous instruction\n\n\n/m magicfile\nSearch for matching magic file\n\n\n/p patternsize\nSearch for pattern of given size\n\n\n/z min max\nSearch for strings of given size\n\n\n/v[?248] num\nLook for a asm.bigendian 32bit value", "crumbs": [ "Reference Card", - "133  Rizin Reference Card" + "134  Rizin Reference Card" ] }, { "objectID": "src/refcard/intro.html#usable-variables-in-expression", "href": "src/refcard/intro.html#usable-variables-in-expression", - "title": "133  Rizin Reference Card", - "section": "133.9 Usable variables in expression", - "text": "133.9 Usable variables in expression\nThe %$? command will display the variables that can be used in any math operation inside the rizin shell. For example, using the % $$ command to evaluate a number or %v to just the value in one format.\nAll commands in rizin that accept a number supports the use of those variables.\n\n\n\n\n\n\n\nCommand\nDescription\n\n\n\n\n$$\nhere (current virtual seek)\n\n\n$?\nlast comparison value\n\n\n$B\nbase address (aligned lowest map address)\n\n\n$b\nblock size\n\n\n$D\ncurrent debug map base address ?v $D @ rsp\n\n\n$DB\nsame as dbg.baddr, progam base address\n\n\n$Fb\nbegin of basic block\n\n\n$FB\nbegin of function\n\n\n$Fe\nend of basic block\n\n\n$FE\nend of function\n\n\n$FS\nfunction size (linear length)\n\n\n$Fs\nsize of the current basic block\n\n\n$FSS\nfunction size (sum bb sizes)\n\n\n$s\nfile size\n\n\n$S\nsection offset\n\n\n$SS\nsection size\n\n\n${ev}\nget value of eval <config variable \n\n\n$r{reg}\nget value of named register", + "title": "134  Rizin Reference Card", + "section": "134.9 Usable variables in expression", + "text": "134.9 Usable variables in expression\nThe %$? command will display the variables that can be used in any math operation inside the rizin shell. For example, using the % $$ command to evaluate a number or %v to just the value in one format.\nAll commands in rizin that accept a number supports the use of those variables.\n\n\n\n\n\n\n\nCommand\nDescription\n\n\n\n\n$$\nhere (current virtual seek)\n\n\n$?\nlast comparison value\n\n\n$B\nbase address (aligned lowest map address)\n\n\n$b\nblock size\n\n\n$D\ncurrent debug map base address ?v $D @ rsp\n\n\n$DB\nsame as dbg.baddr, progam base address\n\n\n$Fb\nbegin of basic block\n\n\n$FB\nbegin of function\n\n\n$Fe\nend of basic block\n\n\n$FE\nend of function\n\n\n$FS\nfunction size (linear length)\n\n\n$Fs\nsize of the current basic block\n\n\n$FSS\nfunction size (sum bb sizes)\n\n\n$s\nfile size\n\n\n$S\nsection offset\n\n\n$SS\nsection size\n\n\n${ev}\nget value of eval <config variable \n\n\n$r{reg}\nget value of named register", "crumbs": [ "Reference Card", - "133  Rizin Reference Card" + "134  Rizin Reference Card" ] }, { "objectID": "src/acknowledgments/credits.html", "href": "src/acknowledgments/credits.html", - "title": "134  Authors & Contributors", + "title": "135  Authors & Contributors", "section": "", "text": "The creation of this book owes much to the extensive list of contributors who have played a crucial role in reviewing, writing, and reporting bugs within the Rizin project and this book. Heartfelt thanks to everyone who has been actively engaged in the development of the book:\n7flying 8dcc Adrian Studer aemmitt-ns Agustín Dall’Alba Ahmed Mohamed Abd El-MAwgood Akshay Krishnan R Alba Mendez Ali Raheem Andrew Hoog Anton Kochkov Antonio Sánchez aoighost Aswin C Austin Hartzheim bemojo2021 Bob131 Braiden Kindt chucklesb ckanibal condret Connor Armand Du Plooy Cyrill Leutwiler David Tomaschik Deepak Chethan Dennis Goodlett Dennis van der Schagt Dhruv Maroo Dhruva Gole dodococo dreamist DZ_ruyk Eric Fangrui Song Florian Best Francesco Tamagni FreeArtMan Gerardo García Peña Giuseppe gogo2464 GPery grepharder Grigory Rechistov GustavoLCR h0pp hdznrrd Heersin hmht Hui Peng Itay Cohen ivan tkachenko izhuer Jacob Rosenthal Jeffrey Crowell John jones martin Judge Dredd Jupiter jvoisin Kali Kaneko karliss Kevin Grandemange Kevin Laeufer Khairul Azhar Kasmiran kij krmpotic Lev Aronsky Liumeo lowsec Luca Di Bartolomeo Lukas Dresel madblobfish Maijin Martin Brunner Masterfox meowmeowxw Michael Scherer Mike mrmacete ms111ds muzlightbeer Nikita Abdullin officialcjunior pancake Paul I Paweł Łukasik Peter C polym (Tim) puddl3glum Pulak Malhotra Rafael Rivera ralexe RandomLive ratijas Razvan Ioan Alexe Ren Kimura Reto Schneider Riccardo Schirone Roman Valls Guimera Rot127 Ryan Geary Sandra Bino SchumBlubBlub seanachao sghctoma shakreiner sivaramaaa SkUaTeR Solomon Sophie Chen Srimanta Barua Surendrajat Sushant Dinesh taiyu TDKPS Thanat0s tick Tomasz Różański Tomáš Golembiovský Tristan Vanellope Vex Woo Vorlent wargio xarkes XYlearn yossizap Yuri Slobodyanyuk Zi Fan Óscar Carrasco", "crumbs": [ "Acknowledgments", - "134  Authors & Contributors" + "135  Authors & Contributors" ] } ] \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index a3f049a1..ae7a4d7d 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,542 +2,546 @@ https://book.rizin.re/index.html - 2024-12-04T06:40:31.070Z + 2024-12-04T06:51:55.820Z https://book.rizin.re/src/introduction/overview.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/introduction/getting_rizin.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/introduction/compilation_portability.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/introduction/windows_compilation.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/introduction/compilation_android.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/first_steps/intro.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/first_steps/commandline_options.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/first_steps/commandline_rizin.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/first_steps/expressions.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/first_steps/basic_debugger_session.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/first_steps/contributing.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/configuration/intro.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.832Z https://book.rizin.re/src/configuration/colors.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/configuration/evars.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.832Z https://book.rizin.re/src/configuration/initial_scripts.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.832Z - https://book.rizin.re/src/configuration/build_variables.html - 2024-12-04T06:40:31.078Z + https://book.rizin.re/src/configuration/compile_time_variables.html + 2024-12-04T06:51:55.828Z + + + https://book.rizin.re/src/configuration/run_time_variables.html + 2024-12-04T06:51:55.832Z https://book.rizin.re/src/basic_commands/intro.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/basic_commands/seeking.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/basic_commands/block_size.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/basic_commands/sections.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/basic_commands/mapping_files.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/basic_commands/print_modes.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/basic_commands/flags.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/basic_commands/write.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/basic_commands/yank_paste.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/basic_commands/comparing_bytes.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/basic_commands/sdb.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/basic_commands/dietline.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/visual_mode/intro.html - 2024-12-04T06:40:31.118Z + 2024-12-04T06:51:55.868Z https://book.rizin.re/src/visual_mode/visual_disassembly.html - 2024-12-04T06:40:31.118Z + 2024-12-04T06:51:55.872Z https://book.rizin.re/src/visual_mode/visual_assembler.html - 2024-12-04T06:40:31.118Z + 2024-12-04T06:51:55.872Z https://book.rizin.re/src/visual_mode/visual_configuration_editor.html - 2024-12-04T06:40:31.118Z + 2024-12-04T06:51:55.872Z https://book.rizin.re/src/visual_mode/visual_panels.html - 2024-12-04T06:40:31.118Z + 2024-12-04T06:51:55.872Z https://book.rizin.re/src/search_bytes/intro.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/search_bytes/basic_searches.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/search_bytes/configurating_the_search.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/search_bytes/pattern_search.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/search_bytes/automation.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/search_bytes/backward_search.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/search_bytes/search_in_assembly.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/search_bytes/searching_aes_keys.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/disassembling/intro.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/disassembling/adding_metadata.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/disassembling/esil.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/analysis/intro.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/analysis/code_analysis.html - 2024-12-04T06:40:31.070Z + 2024-12-04T06:51:55.824Z https://book.rizin.re/src/analysis/variables.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/analysis/types.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/analysis/calling_conventions.html - 2024-12-04T06:40:31.070Z + 2024-12-04T06:51:55.824Z https://book.rizin.re/src/analysis/vtables.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/analysis/syscalls.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/analysis/emulation.html - 2024-12-04T06:40:31.074Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/analysis/symbols.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/analysis/signatures.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/analysis/graphs.html - 2024-12-04T06:40:31.074Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/analysis/cpu_platform_profiles.html - 2024-12-04T06:40:31.074Z + 2024-12-04T06:51:55.828Z https://book.rizin.re/src/scripting/intro.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/scripting/loops.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/scripting/macros.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/scripting/rz-pipe.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/debugger/intro.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/debugger/getting_started.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/debugger/migration.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/debugger/registers.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/debugger/memory_maps.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/debugger/heap.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/debugger/files.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/debugger/revdebug.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/debugger/windows_messages.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/debugger/apple.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/remote_access/remoting_capabilities.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/remote_access/remote_gdb.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/remote_access/windbg.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/intro.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-ax/intro.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-find/intro.html - 2024-12-04T06:40:31.114Z + 2024-12-04T06:51:55.868Z https://book.rizin.re/src/tools/rz-run/intro.html - 2024-12-04T06:40:31.118Z + 2024-12-04T06:51:55.868Z https://book.rizin.re/src/tools/rz-bin/intro.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-bin/file_identification.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-bin/entrypoints.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-bin/imports.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-bin/exports.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-bin/symbols.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-bin/libraries.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-bin/strings.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-bin/program_sections.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-diff/intro.html - 2024-12-04T06:40:31.114Z + 2024-12-04T06:51:55.868Z https://book.rizin.re/src/tools/rz-diff/binary_diffing.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-asm/intro.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-asm/assemble.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-asm/disassemble.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-asm/config.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.860Z https://book.rizin.re/src/tools/rz-gg/rz-gg.html - 2024-12-04T06:40:31.114Z + 2024-12-04T06:51:55.868Z https://book.rizin.re/src/tools/rz-gg/lang.html - 2024-12-04T06:40:31.114Z + 2024-12-04T06:51:55.868Z https://book.rizin.re/src/tools/rz-hash/intro.html - 2024-12-04T06:40:31.114Z + 2024-12-04T06:51:55.868Z https://book.rizin.re/src/tools/rz-hash/rz-hash_tool.html - 2024-12-04T06:40:31.114Z + 2024-12-04T06:51:55.868Z https://book.rizin.re/src/plugins/intro.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/plugins/ioplugins.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/plugins/dev-asm.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/plugins/dev-analysis.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/plugins/dev-bin.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/plugins/dev-other.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/plugins/python.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/plugins/debug.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/plugins/testing.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/plugins/rz-pm.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/crackmes/intro.html - 2024-12-04T06:40:31.102Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/crackmes/ioli/intro.html - 2024-12-04T06:40:31.102Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/crackmes/ioli/ioli_0x00.html - 2024-12-04T06:40:31.102Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/crackmes/ioli/ioli_0x01.html - 2024-12-04T06:40:31.102Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/crackmes/ioli/ioli_0x02.html - 2024-12-04T06:40:31.102Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/crackmes/ioli/ioli_0x03.html - 2024-12-04T06:40:31.102Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/crackmes/ioli/ioli_0x04.html - 2024-12-04T06:40:31.102Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/crackmes/ioli/ioli_0x05.html - 2024-12-04T06:40:31.102Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/crackmes/ioli/ioli_0x06.html - 2024-12-04T06:40:31.102Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/crackmes/ioli/ioli_0x07.html - 2024-12-04T06:40:31.102Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/crackmes/ioli/ioli_0x08.html - 2024-12-04T06:40:31.102Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/crackmes/ioli/ioli_0x09.html - 2024-12-04T06:40:31.102Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/crackmes/avatao/01-reverse4/intro.html - 2024-12-04T06:40:31.094Z + 2024-12-04T06:51:55.844Z https://book.rizin.re/src/crackmes/avatao/01-reverse4/rizin.html - 2024-12-04T06:40:31.094Z + 2024-12-04T06:51:55.844Z https://book.rizin.re/src/crackmes/avatao/01-reverse4/first_steps.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.832Z https://book.rizin.re/src/crackmes/avatao/01-reverse4/main.html - 2024-12-04T06:40:31.094Z + 2024-12-04T06:51:55.844Z https://book.rizin.re/src/crackmes/avatao/01-reverse4/vmloop.html - 2024-12-04T06:40:31.094Z + 2024-12-04T06:51:55.844Z https://book.rizin.re/src/crackmes/avatao/01-reverse4/instructionset.html - 2024-12-04T06:40:31.094Z + 2024-12-04T06:51:55.844Z https://book.rizin.re/src/crackmes/avatao/01-reverse4/bytecode.html - 2024-12-04T06:40:31.078Z + 2024-12-04T06:51:55.832Z https://book.rizin.re/src/crackmes/avatao/01-reverse4/outro.html - 2024-12-04T06:40:31.094Z + 2024-12-04T06:51:55.844Z https://book.rizin.re/src/crackmes/hackthebox/intro.html - 2024-12-04T06:40:31.102Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/crackmes/hackthebox/find-the-easy-pass/intro.html - 2024-12-04T06:40:31.102Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/crackmes/hackthebox/find-the-easy-pass/identification.html - 2024-12-04T06:40:31.094Z + 2024-12-04T06:51:55.848Z https://book.rizin.re/src/crackmes/hackthebox/find-the-easy-pass/find-the-validation-routine.html - 2024-12-04T06:40:31.094Z + 2024-12-04T06:51:55.848Z https://book.rizin.re/src/crackmes/hackthebox/find-the-easy-pass/fire-up-the-debugger.html - 2024-12-04T06:40:31.094Z + 2024-12-04T06:51:55.848Z https://book.rizin.re/src/crackmes/hackthebox/find-the-easy-pass/bonus.html - 2024-12-04T06:40:31.094Z + 2024-12-04T06:51:55.844Z https://book.rizin.re/src/refcard/intro.html - 2024-12-04T06:40:31.106Z + 2024-12-04T06:51:55.856Z https://book.rizin.re/src/acknowledgments/credits.html - 2024-12-04T06:40:31.070Z + 2024-12-04T06:51:55.820Z diff --git a/src/acknowledgments/credits.html b/src/acknowledgments/credits.html index aa166135..2da1caa5 100644 --- a/src/acknowledgments/credits.html +++ b/src/acknowledgments/credits.html @@ -8,7 +8,7 @@ -134  Authors & Contributors – The Rizin Handbook: A Guide to Reverse Engineering with the Rizin Framework +135  Authors & Contributors – The Rizin Handbook: A Guide to Reverse Engineering with the Rizin Framework + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+ + +
+ + + +
+ +
+
+

17  Run-Time Variables

+
+ + + +
+ + + + +
+ + + +
+ + +

Run-time variables (also known as environment variables) can be used to change the default behavior when running rizin or tools.

+

The description of these run-time variables can be accessed by executing the command rizin -hh on a terminal.

+
$ rizin -hh
+...
+Plugins:
+ binrc            /home/username/.local/share/rizin/rc.d/bin-<format> (elf, elf64, mach0, ..)
+ RZ_USER_PLUGINS  /home/username/.local/lib/rizin/plugins
+ RZ_LIB_PLUGINS   /home/username/.local/lib/rizin/plugins
+ RZ_EXTRA_PLUGINS
+Environment:
+ ANSICON             ansicon's W & H of the buffer and w & h of the window in the form of: "WxH (wxh)"
+ DEBUGINFOD_URLS     e bin.dbginfo.debuginfod_urls - use alternative debuginfod server
+ COLUMNS             terminal columns to use
+ RZ_ABORTLEVEL       target log level/severity when to abort (0:DEBUG, 1:VERBOSE, 2:INFO, 3:WARN, 4:ERROR, 5:FATAL)
+ RZ_CURL             whether to use curl (for SSL support)
+ RZ_DEBUG            if defined, show error messages and crash signal
+ RZ_DEBUG_ASSERT     set a breakpoint when hitting an assert
+ RZ_DEBUG_TOOL       debug tool to use when showing error messages and crash signal
+ RZ_DYLDCACHE_FILTER dyld cache filter (MacOS dynamic libraries location(s) at runtime)
+ RZ_HTTP_AUTHFILE    HTTP Authentification user file
+ RZ_LOGCOLORS        should the log output use colors
+ RZ_LOGFILE          logging output filename/path
+ RZ_LOGLEVEL         target log level/severity (0:DEBUG, 1:VERBOSE, 2:INFO, 3:WARN, 4:ERROR, 5:FATAL)
+ RZ_LOGSHOWSOURCES   should the log output contain src info (filename:lineno)
+ RZ_PIPE_IN          rzpipe cmd input (file descriptor)
+ RZ_PIPE_OUT         rzpipe cmd output (file descriptor)
+ RZ_MAGICPATH        /home/username/.local/share/rizin/magic
+ RZ_NOPLUGINS        do not load rizin shared plugins
+ RZ_RCFILE           /home/username/.rizinrc (user preferences, batch script)
+ RZ_DATAHOME         /home/username/.local/share/rizin
+ RZ_VERSION          contains the current version of rizin
+ SFLIBPATH           SFLib syscall library path
+Paths:
+ RZ_PREFIX       /home/username/.local
+ RZ_EXTRA_PREFIX
+ RZ_INCDIR       /home/username/.local/include/librz
+ RZ_LIBDIR       /home/username/.local/lib
+ RZ_SIGDB        /home/username/.local/share/rizin/sigdb
+ RZ_EXTRA_SIGDB
+ RZ_LIBEXT       so
+ + + +
+ + +
+ + + + + \ No newline at end of file diff --git a/src/crackmes/avatao/01-reverse4/bytecode.html b/src/crackmes/avatao/01-reverse4/bytecode.html index 8f06ee00..52ccc7fc 100644 --- a/src/crackmes/avatao/01-reverse4/bytecode.html +++ b/src/crackmes/avatao/01-reverse4/bytecode.html @@ -8,7 +8,7 @@ -125  .bytecode – The Rizin Handbook: A Guide to Reverse Engineering with the Rizin Framework +126  .bytecode – The Rizin Handbook: A Guide to Reverse Engineering with the Rizin Framework