> For the complete documentation index, see [llms.txt](https://ivalexev.gitbook.io/rednote/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ivalexev.gitbook.io/rednote/pentesting-process/software-attacks/binary.md).

# Binary

{% tabs %}
{% tab title="Resources" %}
See my note on [Software Security](https://797548868-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhqLG4rHdEASJgZEcYdEJ%2Fuploads%2FygReuElFj1mWRa2qC8ri%2FSoftwareSecurity.pdf?alt=media\&token=51491027-f493-41ff-96f7-db319244f864).

<table data-header-hidden><thead><tr><th width="210"></th><th></th></tr></thead><tbody><tr><td><a href="https://guyinatuxedo.github.io/">Nightmare</a></td><td>Intro book to to binary exploitation / reverse engineering.</td></tr><tr><td><a href="https://gist.github.com/anvbis/64907e4f90974c4bdd930baeb705dedf">pwntools</a></td><td>Pwntools Cheatsheet</td></tr><tr><td><a href="https://x64.syscall.sh/">syscall_x64</a> </td><td>Syscalls for x64</td></tr><tr><td><a href="https://x86.syscall.sh/">syscall_x86</a></td><td>Syscalls for x86</td></tr><tr><td><a href="https://arm64.syscall.sh/">syscall_arm64</a></td><td>Syscalls for arm64</td></tr><tr><td><a href="https://dogbolt.org/">Decompiler Explorer</a></td><td>Compare tools on the forefront of static analysis in your web browser</td></tr><tr><td><a href="https://github.com/mandiant/GoReSym">GoReSym</a></td><td>Go symbol recovery tool</td></tr></tbody></table>
{% endtab %}

{% tab title="Tools" %}

<table data-header-hidden><thead><tr><th width="210"></th><th></th></tr></thead><tbody><tr><td><a href="https://man7.org/linux/man-pages/man1/objdump.1.html">objdump</a></td><td>Display information from object files like ELF</td></tr><tr><td><a href="https://man7.org/linux/man-pages/man1/ldd.1.html">ldd</a></td><td>Print shared object dependencies</td></tr><tr><td><a href="https://sourceware.org/gdb/">gdb</a></td><td>Debugger</td></tr><tr><td><a href="https://github.com/pwndbg/pwndbg">pwndbg</a></td><td>gdb but with more features</td></tr><tr><td><a href="https://libdebug.org/">Libdebug</a></td><td>A Python library to debug binary executables</td></tr><tr><td><a href="https://github.com/JonathanSalwan/ROPgadget">ROPgadget</a></td><td>Extract ROP gadget</td></tr><tr><td><a href="https://github.com/dnSpy/dnSpy">dnSpy</a></td><td>.NET debugger and assembly editor.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

## Binary Ninja

<details>

<summary><a href="https://docs.binary.ninja/guide/index.html#custom-hotkeys">Keybindings</a></summary>

<table data-header-hidden><thead><tr><th width="152"></th><th></th></tr></thead><tbody><tr><td><strong>macOS</strong></td><td><code>~/Library/Application Support/Binary Ninja</code></td></tr><tr><td><strong>Linux</strong></td><td><code>~/.binaryninja</code></td></tr><tr><td><strong>Windows</strong></td><td><code>%APPDATA%\\Binary Ninja</code></td></tr></tbody></table>

Create a `keybindings.json` file inside the directory and set my keybindings:

{% code title="keybindings.json" overflow="wrap" %}

```json
{
	"" : "",
	"" : ""
}
```

{% endcode %}

</details>

<details>

<summary><a href="https://docs.binary.ninja/guide/debugger/remote-debugging.html">Remote Dubugging</a></summary>

* Download [*debugger-linux.zip*](https://github.com/Vector35/debugger/releases/download/1.0/debugger-linux.zip)
* Move on VM `lldbdebugger-linux/plugins/lldb`

### **Debug Server**

On VM

<pre class="language-bash" data-overflow="wrap"><code class="lang-bash"><strong>lldb-server p --server --listen 0.0.0.0:31337
</strong></code></pre>

On Binary Ninja

{% code overflow="wrap" %}

```
"Debugger" —> "Connect to Debug Server”

Platform: remote-linux
Host: <IP>
Port: 31337

Reopen "Debugger" —> "Connect to Debug Server”

Working Directory: <PATH_WHERE_UPLOAD_AND_RUN_ELF_ON_VM> # edit only this
```

{% endcode %}

### **Remote Process**

On VM

{% code overflow="wrap" %}

```bash
./lldb-server g 0.0.0.0:31337 -- <PATH_ELF> <ARGs>
```

{% endcode %}

{% code overflow="wrap" %}

```bash
./lldb-server g 0.0.0.0:31337 --attach <PID>
```

{% endcode %}

On Binary Ninja

{% code overflow="wrap" %}

```
"Debugger" —> "Remote Process Settings"

Plugin: gdb-remote
Host: <IP>
Port: 31337
```

{% endcode %}

</details>

## [GDB](https://sourceware.org/gdb/current/onlinedocs/gdb.html/index.html)

To be expanded with [PEDA](https://github.com/longld/peda), [GEF](https://github.com/hugsy/gef) or [<mark style="color:red;">**PWNDBG**</mark>](https://github.com/pwndbg/pwndbg).

### Start

<table data-header-hidden><thead><tr><th width="278"></th><th></th></tr></thead><tbody><tr><td><code>gdb &#x3C;ELF></code></td><td>Run gdb on that program.  Be careful with addresses (it would be better to use PID).</td></tr><tr><td><code>gdb --pid &#x3C;PID></code></td><td>Run gdb on a process. Run the program in the background, get PID and provide it to gdb.</td></tr><tr><td><code>gdb --args &#x3C;ELF> &#x3C;ARGs></code></td><td>Run gdb on that program passing it arguments.</td></tr></tbody></table>

### Execution

<table data-header-hidden><thead><tr><th width="307"></th><th></th></tr></thead><tbody><tr><td><code>file &#x3C;ELF></code></td><td>Load the program to analyze</td></tr><tr><td><code>set args &#x3C;ARGs></code></td><td>Set the arguments to use on each bugger run.</td></tr><tr><td><code>r</code></td><td>Run</td></tr><tr><td><code>r &#x3C;ARGs></code></td><td>Run with arguments</td></tr><tr><td><code>r ${python3 -c ‘print "\xBYTES"’}</code></td><td>Run with byte arguments using Python</td></tr><tr><td><code>r ${echo -e “\xBYTES”}</code></td><td>run with byte arguments using Echo</td></tr></tbody></table>

### Breakpoints

<table data-header-hidden><thead><tr><th width="308"></th><th></th></tr></thead><tbody><tr><td><code>b &#x3C;function></code> <br><code>b *&#x3C;address></code></td><td>Set a breakpoint. <br>Also possible to do: <code>b *main+10</code></td></tr><tr><td> <code>i b</code></td><td>Info breakpoint</td></tr><tr><td><code>enable &#x3C;ID></code></td><td>Enable breakpoints. <br>If no ID is specified, enable all breakpoints.</td></tr><tr><td><code>disable &#x3C;ID></code></td><td>Disable breakpoints. <br>If no ID is specified, disable all breakpoints.</td></tr><tr><td><code>d &#x3C;ID></code></td><td>Delete breakpoint<br>If no ID is specifyied, deletes all breakpoints.</td></tr><tr><td><code>c</code></td><td>Continue. Normal execution.</td></tr><tr><td><code>s</code></td><td>Step. IN function.</td></tr><tr><td><code>n</code></td><td>Next. NO IN function.</td></tr><tr><td><code>finish</code></td><td>Continue until the current function returns.</td></tr><tr><td><code>k</code></td><td>Kill. Stop the current execution.</td></tr></tbody></table>

### Visualization

<table data-header-hidden><thead><tr><th width="289"></th><th></th></tr></thead><tbody><tr><td><code>disassemble &#x3C;FUNCTION></code></td><td>Get assembly and their memory addresses.</td></tr><tr><td><code>i fu</code></td><td>Get the list of program functions with their addresses.</td></tr><tr><td><code>bt [full]</code></td><td>Show backtrace (function calls list). <br>With <code>full</code> print even the local variables of each frame, if you have access to them.</td></tr><tr><td><code>i s</code></td><td>Info Stack Frame.</td></tr><tr><td><code>i f</code></td><td>Info Current Stack Frame.<br><em>(ex. $RIP in BOF)</em></td></tr><tr><td><code>i r</code> <br><code>i all-r</code></td><td>Info Registers.</td></tr><tr><td><code>i dll</code></td><td>list of used DLLs</td></tr><tr><td><code>p/&#x3C;F> &#x3C;expr></code></td><td>Print what you want in the specified <a href="#format">format</a> <code>&#x3C;F></code>.<br><em>ex. <code>p/x $esp</code></em> <em><code>p/x $esp+8</code></em> <em><code>p &#x3C;FUN></code></em> <em><code>p &#x3C;VAR></code></em></td></tr><tr><td><code>x/&#x3C;N>&#x3C;F>&#x3C;U> &#x3C;addr></code></td><td>Print and display memory only once. Specifies how many elements (<code>&#x3C;N></code>), in what <a href="#format">format</a> (<code>&#x3C;F></code>), and in what <a href="#unit">units</a> (<code>&#x3C;U></code>) to display starting at address <code>&#x3C;addr></code>.<br><em>ex. <code>x/40x $esp</code></em> <em><code>x/5i $pc</code></em> <em>(next 5 instruction)</em></td></tr><tr><td><code>display/&#x3C;N>&#x3C;F>&#x3C;U> &#x3C;addr></code></td><td>As x/ but are saved and printed/displayed at each step.<br><code>i display</code><br><code>undisplay &#x3C;ID></code><br><code>enable display &#x3C;ID></code><br><code>disable display &#x3C;ID></code><br>If you don't put ID it applies to all.<br><em>ex. <code>display/5i $pc</code> (next 5 instruction)</em></td></tr></tbody></table>

{% tabs %}
{% tab title="Format" %}
Format

* `a` Pointer.&#x20;
* `c` Read as integer, print as character.&#x20;
* `d` Integer, signed decimal.&#x20;
* `f` Floating point number.&#x20;
* `o` Integer, print as octal.&#x20;
* `s` String.&#x20;
* `t` Integer, print as binary *(t = "two")*.&#x20;
* `u` Integer, unsigned decimal.&#x20;
* `x` Integer, print as hexadecimal.&#x20;
* `i` Disassembly.
  {% endtab %}

{% tab title="Unit" %}
Unit

* `b` Byte&#x20;
* `h` Half-word (2 bytes)&#x20;
* `w` Word (4 bytes)&#x20;
* `g` Giant word (8 bytes)
  {% endtab %}

{% tab title="Simbols" %}

* `variable` Contents of a variable
* `&variable` Address of a variable
* `*address` Contents of an address
  {% endtab %}
  {% endtabs %}

### Edit memory

<table data-header-hidden><thead><tr><th width="297"></th><th></th></tr></thead><tbody><tr><td><code>set {type}address = value</code></td><td>Change the value of the addresses.<br>ex. <code>set{int}0x650000 = 0x42</code> <br><code>set{char[1]}0x650000 = 0x42</code></td></tr><tr><td><code>set variable = value</code></td><td>Change the value of variables</td></tr><tr><td><code>set $reg = value</code></td><td>Change the value of the registers</td></tr><tr><td><code>set *address = value</code></td><td>Change the value of an address</td></tr></tbody></table>

### Utility

<table data-header-hidden><thead><tr><th width="306"></th><th></th></tr></thead><tbody><tr><td><code>call &#x3C;FUNCTION>()</code></td><td>Call function.<br>ex. <code>call (void)win()</code></td></tr><tr><td><code>echo $((16#&#x3C;NUM>))</code></td><td>From bash convert hex to decimal.</td></tr><tr><td><code>r &#x3C;&#x3C; &#x3C;CommandFile></code></td><td>It is possible to specify a file with the inputs that should be given to the program in read, scanf, etc.<br>Like <code>cat &#x3C;CommandFile> | ./&#x3C;ELF></code></td></tr><tr><td><code>j *&#x3C;EXPRESSION></code></td><td>Jump and force execution to a specific address (*addr, *$reg, function).</td></tr></tbody></table>

### pwndbg

<table data-header-hidden><thead><tr><th width="267"></th><th></th></tr></thead><tbody><tr><td><code>pwndbg [&#x3C;TOPIC>]</code></td><td>Print info about pwndbg commands</td></tr><tr><td><code>vmmap</code></td><td>Display memory mappings information</td></tr><tr><td><code>context [&#x3C;SECTION>]</code></td><td>Display context or a given context section<br>(regs, disasm, args, code, stack, backtrace,<br>expressions, ghidra, threads)</td></tr><tr><td><code>search &#x3C;WHAT></code></td><td>Search memory for a given value</td></tr><tr><td><code>telescope &#x3C;WHERE> [&#x3C;COUNT>]</code></td><td>Examine memory dereferencing valid pointers</td></tr><tr><td><code>hexdump &#x3C;WHERE> [&#x3C;COUNT>]</code></td><td>Print hexdump of given address</td></tr><tr><td><code>xinfo &#x3C;WHERE></code></td><td>Show offsets of the specified address from<br>various useful locations</td></tr><tr><td><code>retaddr</code></td><td>Print return addresses on the stack</td></tr><tr><td><code>canary</code></td><td>Print the global stack canary/cookie value<br>and finds canaries on the stack</td></tr><tr><td><code>xuntil</code> </td><td>Continue until an address or function</td></tr><tr><td><code>nextcall</code></td><td>Continue to next call instruction</td></tr><tr><td><code>nextjmp</code></td><td>Continue to next jump instruction</td></tr><tr><td><code>nextret</code></td><td>Continue to next return-like instruction</td></tr><tr><td><code>stepret</code></td><td>Step until a ret instruction is found</td></tr><tr><td><code>checksec</code></td><td>Print binary mitigations status</td></tr><tr><td><code>piebase</code></td><td>Print the relocated binary base address</td></tr><tr><td><code>got</code></td><td>Print symbols in the .got section</td></tr><tr><td><code>gotplt</code></td><td>Print symbols in the .got.plt section</td></tr><tr><td><code>plt</code></td><td>Print symbols in the .plt section</td></tr><tr><td><code>tls</code></td><td>Print thread local storage address</td></tr><tr><td><code>distance &#x3C;WHERE1> &#x3C;WHERE2></code></td><td>Compute difference between two addresses</td></tr><tr><td><code>procinfo</code></td><td>Display process information</td></tr><tr><td><code>heap_config</code></td><td>Show glibc allocator hacking configuration</td></tr><tr><td><code>heap</code></td><td>Iteratively print chunks on heap (glibc only)</td></tr><tr><td><code>vis_heap_chunks</code></td><td>Visualize chunks on a heap</td></tr><tr><td><code>try_free &#x3C;ADDRESS></code>   </td><td>Check what would happen if free was called<br>with given address</td></tr></tbody></table>

## [PwnTools](https://docs.pwntools.com/en/stable/)

{% code overflow="wrap" %}

```bash
checksec <ELF>
pwn checksec <ELF>
```

{% endcode %}

### Context

<table data-header-hidden><thead><tr><th width="210"></th><th></th></tr></thead><tbody><tr><td>Architecture</td><td><code>context.arch = '&#x3C;ARCH>'</code> <br><code>'aarch64'</code>, <code>'arm'</code>, <code>'i386'</code>, <code>'amd64'</code></td></tr><tr><td>Log Output</td><td><p><code>context.log_level = '&#x3C;VALUE>'</code></p><p><code>'debug'</code>, <code>'info'</code>, <code>'warn'</code>, <code>'error'</code></p></td></tr><tr><td>Endianness</td><td><p><code>context.endian = '&#x3C;ENDIANNESS>'</code> </p><p><code>'big'</code>, <code>'little'</code></p></td></tr></tbody></table>

### Start

<table data-header-hidden><thead><tr><th width="210"></th><th></th></tr></thead><tbody><tr><td>ELF</td><td><code>elf = ELF('&#x3C;PATH_BINARY>')</code><br><code>libc = ELF("./libc.so.6")</code></td></tr><tr><td>Process</td><td><code>p = process('&#x3C;PATH_BINARY>')</code></td></tr><tr><td>Remote</td><td><code>p = remote('&#x3C;IP/DOMAIN>', PORT)</code></td></tr><tr><td>Hybrid</td><td><p><code>elf = ELF('&#x3C;PATH_BINARY>')</code> </p><p><code>p = elf.process()</code></p></td></tr></tbody></table>

### Debugger

<table data-header-hidden><thead><tr><th width="210"></th><th></th></tr></thead><tbody><tr><td><a href="https://docs.pwntools.com/en/stable/gdb.html">Debugger GDB</a></td><td><code>p = gdb.debug('&#x3C;PATH_BINARY>', aslr=False, gdbscript='b *main+123')</code></td></tr></tbody></table>

### Encoding e Packing

<table data-header-hidden><thead><tr><th width="210"></th><th></th></tr></thead><tbody><tr><td>Hex</td><td><code>enhex(b'/flag')</code>   <em>('2f666c6167')</em><br><code>unhex('2f666c6167')</code>   <em>(b'/flag')</em></td></tr><tr><td>Base64</td><td><p><code>b64e(b'/flag')</code>   <em>('L2ZsYWc=')</em> </p><p><code>b64d('L2ZsYWc=')</code>   <em>(b'/flag')</em></p></td></tr><tr><td>Packing</td><td><p><code>p32(0x41424344)</code>   <em>(b'\x44\x43\x42\x41')</em></p><p><code>p8</code>, <code>p16</code>, <code>p64</code></p></td></tr><tr><td>Unpacking</td><td><p><code>u32(b'\x44\x43\x42\x41')</code>   <em>(0x41424344)</em></p><p><code>u8</code>, <code>u16</code>, <code>u64</code></p></td></tr></tbody></table>

### Address

<table data-header-hidden><thead><tr><th width="210"></th><th></th></tr></thead><tbody><tr><td>Function address</td><td><code>address = elf.sym['&#x3C;Name_Function>']</code><br><code>address = elf.symbols.&#x3C;Name_Function></code><br><code>address = elf.plt[’&#x3C;Name_Function>’]</code> <em>(in PLT)</em><br><code>address = elf.got[’&#x3C;Name_Function>’]</code> <em>(in GOT)</em></td></tr><tr><td>String address</td><td><code>address = next(elf.search(b'&#x3C;STRING>'))</code> <br>Or with ghidra in <code>.rodata</code>, <code>.text</code></td></tr></tbody></table>

### Cyclic

<table data-header-hidden><thead><tr><th width="210"></th><th></th></tr></thead><tbody><tr><td>Create Search String</td><td><code>cyclic(16)</code>   <em>(b'aaaabaaacaaadaaa')</em><br><code>cyclic(16, n=8)</code>   <em>(b'aaaaaaaabaaaaaaa')</em></td></tr><tr><td>Find Offset</td><td><p><code>cyclic_find(0x61616164)</code>   <em>(12)</em> <br><code>cyclic_find(0x6161616161616162, n=8)</code>   <em>(8)</em> </p><p><code>cyclic_find(io.corefile.fault_addr, n=8)</code> <em>(in BOF)</em> <br><em>In BOF use <code>setuid=False</code> in <code>p = process()</code></em></p></td></tr></tbody></table>

### Shellcode

[Shellcraft](https://docs.pwntools.com/en/stable/shellcraft.html), must be NULL-free.

<table data-header-hidden><thead><tr><th width="210"></th><th></th></tr></thead><tbody><tr><td>Assembly</td><td><code>code = shellcraft.cat('/flag')</code> <br><code>code = shellcraft.amd64.linux.sh()</code></td></tr><tr><td>Bytecode</td><td><code>shellcode = asm(code)</code>   <em>(use the context architecture)</em><br><code>shellcode = asm(code, arch='x86_64')</code></td></tr></tbody></table>

### [ROP](https://docs.pwntools.com/en/stable/rop/rop.html)

<table data-header-hidden><thead><tr><th width="173"></th><th></th></tr></thead><tbody><tr><td>Start</td><td><p><code>rop = ROP(elf)</code> </p><p><code>rop = ROP(elf, badchars=b'\n')</code> <em>(char not to be used in the chain)</em></p><p><code>rop = ROP([elf, libc])</code>  <em>(specify double elf)</em></p></td></tr><tr><td>Extract Gadget</td><td><p><code>pop_ = rop.find_gadget(['pop &#x3C;REG>', 'ret']).address</code> </p><p><code>pop_ = rop.&#x3C;REG>.address</code> <br>or <a href="https://github.com/JonathanSalwan/ROPgadget">ROPgadget</a>.</p></td></tr><tr><td>ROP chain</td><td><p><code>rop.call(&#x3C;ADDR_FUNCTION>, [&#x3C;ADDR_ARG1>, ... ])</code> <br></p><p><code>rop.puts(); rop.main()</code> <em>(adds puts and main to the chain)</em> <code>rop.chain()</code> <em>(builds the chain with the elements called before)</em> <code>rop.dump()</code> (text representation, to be put in <code>log.info(X)</code>)<br><code>rop.clear()</code> <em>(clears the rop chain)</em><br><br><code>rop.execve(next(libc.search(b'/bin/sh\0')), 0, 0)</code> <em>(calls execv with parameters)</em> </p></td></tr><tr><td>Set Base Address (ex. libc)</td><td><code>libc = ELF(&#x3C;PATH_LIBC>)</code> <em>(ex ./glibc/libc.so.6)</em><br><code>libc.address = &#x3C;INT_ADDRESS_BASE></code> <br><code>rop_libc = ROP(libc)</code> <em>(after set base libc)</em></td></tr></tbody></table>

### Format String

{% tabs %}
{% tab title="Format" %}

<table data-header-hidden><thead><tr><th width="129"></th><th></th></tr></thead><tbody><tr><td><code>%p</code></td><td>Pointer</td></tr><tr><td><code>%s</code></td><td>String</td></tr><tr><td><code>%d</code></td><td>Int</td></tr><tr><td><code>%x</code></td><td>Hex</td></tr><tr><td><code>%c</code></td><td>Char</td></tr><tr><td><code>%n</code></td><td>Writes the number of characters printed in the specified pointer.<br><code>%n</code> = int (8 byte)<br><code>%hn</code> = short (4 byte)<br><code>%hhn</code> = byte (1 byte)</td></tr><tr><td><code>%&#x3C;P>x</code></td><td>Specifies the precision &#x3C;P> (filled with 0)</td></tr><tr><td><code>%&#x3C;N>$x</code></td><td>Take the &#x3C;N>-th argument</td></tr></tbody></table>
{% endtab %}

{% tab title="Read" %}
Find the buffer in which you are writing with `%<N>$x` where `N` increments.\
When you reach the buffer take note of `N` which will be the `OFFSET`

{% code overflow="wrap" %}

```
<ADDR_little> %<OFFSET>$x
```

{% endcode %}
{% endtab %}

{% tab title="Write" %}
Find the buffer in which you are writing with `%<N>$x` where `N` increments.\
When you reach the buffer take note of `N` which will be the `OFFSET` \
`VAL` is the value that you want to write.

{% code overflow="wrap" %}

```
<ADDR_little>%<VAL-len(ADDR)>c%<OFFSET>$n
```

{% endcode %}

{% code overflow="wrap" %}

```
%<VAL>c%<OFFSET>$n<ADDR_little> 
BUT for every 8 characters you insert, increase the offset by 1
```

{% endcode %}
{% endtab %}
{% endtabs %}

<table data-header-hidden><thead><tr><th width="198"></th><th></th></tr></thead><tbody><tr><td><a href="https://docs.pwntools.com/en/stable/fmtstr.html#pwnlib.fmtstr.fmtstr_payload">fmtstr_payload</a></td><td><p><code>fmtstr_payload(offset, writes, numbwritten=0, write_size='byte')</code> </p><ul><li><code>offset</code>: Offset to the buffer</li><li><code>writes</code>: Dictionary with address:value <br><code>{addr: value, addr2: value2, etc.}</code></li><li><code>numbwritten</code>: Number of bytes already written by printf()<br>ex. <code>printf(hello &#x3C;VAR>)</code> = 6</li><li><code>write_size</code>: The write size: byte, short or int (hhn, hn or n)</li></ul><p>Note: Set the right <code>&#x3C;ARCH></code></p></td></tr></tbody></table>

## [ANGR](https://angr.io/)

<details>

<summary>Code</summary>

{% code overflow="wrap" %}

```python
import angr
import claripy
import sys

FILE        = './<ELF>'
FLAG_LENGTH = 30
FLAG_KNOW   = 'FLAG{'
FIND_ADDR   = 0x1def 
AVOID_ADDR  = 0x1df8

# Define program
project = angr.Project(FILE, main_opts={"base_addr": 0x0}) # auto_load_libs=False

# Define the initial state simply
OPTION_NO_ERROR = {angr.options.ZERO_FILL_UNCONSTRAINED_MEMORY, angr.options.ZERO_FILL_UNCONSTRAINED_REGISTERS}
initial_state = project.factory.entry_state(add_options = OPTION_NO_ERROR)

# ---------------- OR ----------------
# OPTIONAL: Define variable format 
# known_chars = [claripy.BVV(FLAG_KNOW[i]) for i in range(len(FLAG_KNOW))]
# flag_chars  = [claripy.BVS(f"flag_{i}",8) for i in range(FLAG_LENGTH-len(FLAG_KNOW))]
# flag_input  = claripy.Concat(*known_chars+flag_chars)

# OPTIONAL: Define how to make the input
# Define initial state with interactive input
# initial_state = project.factory.entry_state(stdin=flag_input, add_options = OPTION_NO_ERROR)
# Define initial state with input from argument
# initial_state = project.factory.entry_state(args=[FILE, flag_input], add_options = OPTION_NO_ERROR)
# ------------------------------------

# Create a simulator with the initial state
simgr = project.factory.simulation_manager(initial_state)

# Start the exploration of the program path
simgr.explore(find=FIND_ADDR, avoid=AVOID_ADDR)

# If Angr finds a path that meets the success criterion.
if simgr.found:
    # Extract the input that led to the path to success
    flag_solution = simgr.found[0].posix.dumps(0)
    print("Flag found:", flag_solution.decode())
else:
    print("No flag found.")

# ---------------- OR ----------------
# If there are multiple inputs
# if simgr.found:
#     print("[+] Input:")
#     for state in simgr.found:
#         solution = state.posix.dumps(0)
#         print(solution.decode())
# else:
#     print("No solution found.")
# ------------------------------------
```

{% endcode %}

</details>
