Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++ Support #13

Open
nbruns1 opened this issue Jul 26, 2023 · 5 comments
Open

C++ Support #13

nbruns1 opened this issue Jul 26, 2023 · 5 comments

Comments

@nbruns1
Copy link

nbruns1 commented Jul 26, 2023

Is it planned to support C++ applications, and what would be needed to develop the support?

@RobinDavid
Copy link
Collaborator

Hi @nbruns1. There is no specific plans to support C++ applications at the moment. For sure the Program loader will be very limited (as it only contains symbolic routines for C), but the  CleLoader load all the shared libraries so it will enables covering most of the C++ runtime. Then it is unclear for me what are the specificities of the C++ runtime that could be problematic.

If you give it a look, I'd be happy to help.

@nbruns1
Copy link
Author

nbruns1 commented Aug 2, 2023

Here a quick hello world example that is not running :)

hello-world-example.zip

It produces the following Error:

WARNING:tritondse.executor:symbol _ZSt4cout imported but unsupported
INFO:tritondse.executor:Starting emulation
INFO:tritondse.executor:configure pstate: time_inc:1e-05 solver:Z3 timeout:5000
WARNING:tritondse.executor:Memory violation: (Perm.R: 0xffffffffffffffe8 unmapped)
INFO:tritondse.executor:Emulation done [ret:0] (time:0.01s)
INFO:tritondse.executor:Instructions executed: 69 symbolic branches: 0
INFO:tritondse.executor:Memory usage: 754.62Mb

If we disable the memory_segmentation, then we get:

WARNING:tritondse.executor:symbol _ZSt4cout imported but unsupported
INFO:tritondse.executor:Starting emulation
INFO:tritondse.executor:configure pstate: time_inc:1e-05 solver:Z3 timeout:5000
ERROR:tritondse.executor:PC=0, is it normal ? (stop)
INFO:tritondse.executor:Emulation done [ret:0] (time:0.01s)
INFO:tritondse.executor:Instructions executed: 97 symbolic branches: 0
INFO:tritondse.executor:Memory usage: 753.16Mb

Is this the expected behavior? Did we overlook something? @RobinDavid

@RobinDavid
Copy link
Collaborator

Thanks! You did it right the issue is on our side. To test I just added to your script:

from tritondse.probes.basic_trace import BasicDebugTrace

# in main
executor.cbm.register_probe(BasicDebugTrace())

# in __name__
tritondse.logging.enable(logging.DEBUG,"probe.basictrace")

This print the execution trace. We are crashing std::ostream::sentry::sentry(std::ostream::sentry *__hidden this, std::ostream *) by reading rax which is 0 there (and thus unmapped). This function is called by the cout << in the main.

Indeed we are not handling things correctly, my first guess is that we are no initializing the program context correctly (init, init_array etc) in __libc_start_main as a provide a symbolic stub that is rather simple. I would need to investigate it more in depth.

@nbruns1
Copy link
Author

nbruns1 commented Aug 2, 2023

@RobinDavid You’re welcome. Can you please explain how you know that TrintonDSE is crashing at this specific function call? Is there a way to enable the logging of the executed function calls?

@RobinDavid
Copy link
Collaborator

I just followed the various calls and saw that I ended up there. You can quickly create a reverse dict to get symbols associated to an address by manipulating the cle object. Here is a small snippet:

reverse_syms = {}

def inst_callback(ex: SymbolicExecutor, ps: ProcessState, ins: 'Instruction'):
    addr = ins.getAddress()
    if addr in reverse_syms:
        print(f"Enter: {reverse_syms[addr]}")
    print(f"[tid:{ins.getThreadId()}] {ex.trace_offset} [0x{addr:x}]: {ins.getDisassembly()}")


def main(argv):
    
    p = CleLoader(argv[1])

    for sym in p.ld.symbols:
        if sym.is_function:
            reverse_syms[sym.rebased_addr] = sym.name
     # [snip]

    executor.cbm.register_pre_instruction_callback(inst_callback)

    executor.load(p)
    executor.run()

This generated me the following trace:

Enter: _start
[tid:0] 0 [0x401070]: xor ebp, ebp
[tid:0] 1 [0x401072]: mov r9, rdx
[tid:0] 2 [0x401075]: pop rsi
[tid:0] 3 [0x401076]: mov rdx, rsp
[tid:0] 4 [0x401079]: and rsp, 0xfffffffffffffff0
[tid:0] 5 [0x40107d]: push rax
[tid:0] 6 [0x40107e]: push rsp
[tid:0] 7 [0x40107f]: xor r8d, r8d
[tid:0] 8 [0x401082]: xor ecx, ecx
[tid:0] 9 [0x401084]: lea rdi, [rip + 0xce]
[tid:0] 10 [0x40108b]: call qword ptr [rip + 0x2f2f]
Enter: __libc_start_main
[tid:0] 11 [0x827700]: push r15
[tid:0] 12 [0x827702]: mov r15, rcx
[tid:0] 13 [0x827705]: push r14
[tid:0] 14 [0x827707]: push r13
[tid:0] 15 [0x827709]: push r12
[tid:0] 16 [0x82770b]: push rbp
[tid:0] 17 [0x82770c]: mov ebp, esi
[tid:0] 18 [0x82770e]: push rbx
[tid:0] 19 [0x82770f]: mov rbx, rdx
[tid:0] 20 [0x827712]: sub rsp, 0x18
[tid:0] 21 [0x827716]: mov qword ptr [rsp], rdi
[tid:0] 22 [0x82771a]: test r9, r9
[tid:0] 23 [0x82771d]: je 0x82772b
[tid:0] 24 [0x82772b]: mov rax, qword ptr [rip + 0x1ab77e]
[tid:0] 25 [0x827732]: mov eax, dword ptr [rax]
[tid:0] 26 [0x827734]: mov r12d, eax
[tid:0] 27 [0x827737]: mov dword ptr [rsp + 8], eax
[tid:0] 28 [0x82773b]: and r12d, 2
[tid:0] 29 [0x82773f]: jne 0x827823
[tid:0] 30 [0x827745]: mov rax, qword ptr [rip + 0x1ab854]
[tid:0] 31 [0x82774c]: mov r13, qword ptr [rax]
[tid:0] 32 [0x82774f]: test r15, r15
[tid:0] 33 [0x827752]: je 0x827785
[tid:0] 34 [0x827785]: mov r15, qword ptr [rip + 0x1ab7fc]
[tid:0] 35 [0x82778c]: mov r14, qword ptr [r15]
[tid:0] 36 [0x82778f]: mov rcx, qword ptr [r14 + 0xa0]
[tid:0] 37 [0x827796]: test rcx, rcx
[tid:0] 38 [0x827799]: je 0x8277ac
[tid:0] 39 [0x8277ac]: mov rdi, qword ptr [r14 + 0x108]
[tid:0] 40 [0x8277b3]: test rdi, rdi
[tid:0] 41 [0x8277b6]: je 0x827766
[tid:0] 42 [0x827766]: mov rdi, qword ptr [r15]
[tid:0] 43 [0x827769]: call 0x826380
[tid:0] 44 [0x826380]: jmp qword ptr [rip + 0x1ace32]
Enter: _dl_audit_preinit
[tid:0] 45 [0xb16c10]: mov eax, dword ptr [rip + 0x1b242]
[tid:0] 46 [0xb16c16]: test eax, eax
[tid:0] 47 [0xb16c18]: jne 0xb16c20
[tid:0] 48 [0xb16c1a]: ret
[tid:0] 49 [0x82776e]: test r12d, r12d
[tid:0] 50 [0x827771]: jne 0x827805
[tid:0] 51 [0x827777]: mov rdi, qword ptr [rsp]
[tid:0] 52 [0x82777b]: mov rdx, rbx
[tid:0] 53 [0x82777e]: mov esi, ebp
[tid:0] 54 [0x827780]: call 0x827650
[tid:0] 55 [0x827650]: sub rsp, 0x98
[tid:0] 56 [0x827657]: mov qword ptr [rsp + 8], rdi
[tid:0] 57 [0x82765c]: lea rdi, [rsp + 0x20]
[tid:0] 58 [0x827661]: mov dword ptr [rsp + 0x14], esi
[tid:0] 59 [0x827665]: mov qword ptr [rsp + 0x18], rdx
[tid:0] 60 [0x82766a]: mov rax, qword ptr fs:[0x28]
[tid:0] 61 [0x827673]: mov qword ptr [rsp + 0x88], rax
[tid:0] 62 [0x82767b]: xor eax, eax
[tid:0] 63 [0x82767d]: call 0x83c250
Enter: _setjmp
[tid:0] 64 [0x83c250]: xor esi, esi
[tid:0] 65 [0x83c252]: jmp 0x83c1b0
Enter: __sigsetjmp
[tid:0] 66 [0x83c1b0]: mov qword ptr [rdi], rbx
[tid:0] 67 [0x83c1b3]: mov rax, rbp
[tid:0] 68 [0x83c1b6]: xor rax, qword ptr fs:[0x30]
[tid:0] 69 [0x83c1bf]: rol rax, 0x11
[tid:0] 70 [0x83c1c3]: mov qword ptr [rdi + 8], rax
[tid:0] 71 [0x83c1c7]: mov qword ptr [rdi + 0x10], r12
[tid:0] 72 [0x83c1cb]: mov qword ptr [rdi + 0x18], r13
[tid:0] 73 [0x83c1cf]: mov qword ptr [rdi + 0x20], r14
[tid:0] 74 [0x83c1d3]: mov qword ptr [rdi + 0x28], r15
[tid:0] 75 [0x83c1d7]: lea rdx, [rsp + 8]
[tid:0] 76 [0x83c1dc]: xor rdx, qword ptr fs:[0x30]
[tid:0] 77 [0x83c1e5]: rol rdx, 0x11
[tid:0] 78 [0x83c1e9]: mov qword ptr [rdi + 0x30], rdx
[tid:0] 79 [0x83c1ed]: mov rax, qword ptr [rsp]
[tid:0] 80 [0x83c1f1]: xor rax, qword ptr fs:[0x30]
[tid:0] 81 [0x83c1fa]: rol rax, 0x11
[tid:0] 82 [0x83c1fe]: mov qword ptr [rdi + 0x38], rax
[tid:0] 83 [0x83c202]: jmp 0x83c210
[tid:0] 84 [0x83c210]: push rbx
[tid:0] 85 [0x83c211]: mov rbx, rdi
[tid:0] 86 [0x83c214]: test esi, esi
[tid:0] 87 [0x83c216]: jne 0x83c220
[tid:0] 88 [0x83c218]: mov dword ptr [rbx + 0x40], esi
[tid:0] 89 [0x83c21b]: xor eax, eax
[tid:0] 90 [0x83c21d]: pop rbx
[tid:0] 91 [0x83c21e]: ret
[tid:0] 92 [0x827682]: test eax, eax
[tid:0] 93 [0x827684]: jne 0x8276d1
[tid:0] 94 [0x827686]: mov rax, qword ptr fs:[0x300]
[tid:0] 95 [0x82768f]: mov qword ptr [rsp + 0x68], rax
[tid:0] 96 [0x827694]: mov rax, qword ptr fs:[0x2f8]
[tid:0] 97 [0x82769d]: mov qword ptr [rsp + 0x70], rax
[tid:0] 98 [0x8276a2]: lea rax, [rsp + 0x20]
[tid:0] 99 [0x8276a7]: mov qword ptr fs:[0x300], rax
[tid:0] 100 [0x8276b0]: mov rax, qword ptr [rip + 0x1ab8e9]
[tid:0] 101 [0x8276b7]: mov rsi, qword ptr [rsp + 0x18]
[tid:0] 102 [0x8276bc]: mov edi, dword ptr [rsp + 0x14]
[tid:0] 103 [0x8276c0]: mov rdx, qword ptr [rax]
[tid:0] 104 [0x8276c3]: mov rax, qword ptr [rsp + 8]
[tid:0] 105 [0x8276c8]: call rax
Enter: main
[tid:0] 106 [0x401159]: push rbp
[tid:0] 107 [0x40115a]: mov rbp, rsp
[tid:0] 108 [0x40115d]: lea rax, [rip + 0xea0]
[tid:0] 109 [0x401164]: mov rsi, rax
[tid:0] 110 [0x401167]: lea rax, [rip + 0x2ed2]
[tid:0] 111 [0x40116e]: mov rdi, rax
[tid:0] 112 [0x401171]: call 0x401040
[tid:0] 113 [0x401040]: jmp qword ptr [rip + 0x2fc2]
Enter: _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
[tid:0] 114 [0x638d00]: endbr64
[tid:0] 115 [0x638d04]: push rbp
[tid:0] 116 [0x638d05]: mov rbp, rdi
[tid:0] 117 [0x638d08]: push rbx
[tid:0] 118 [0x638d09]: sub rsp, 8
[tid:0] 119 [0x638d0d]: test rsi, rsi
[tid:0] 120 [0x638d10]: je 0x638d38
[tid:0] 121 [0x638d12]: mov rdi, rsi
[tid:0] 122 [0x638d15]: mov rbx, rsi
[tid:0] 123 [0x638d18]: call 0x59d900
[tid:0] 124 [0x59d900]: jmp qword ptr [rip + 0x1b2362]
[tid:0] 125 [0x638d1d]: mov rsi, rbx
[tid:0] 126 [0x638d20]: mov rdi, rbp
[tid:0] 127 [0x638d23]: mov rdx, rax
[tid:0] 128 [0x638d26]: call 0x59e710
[tid:0] 129 [0x59e710]: jmp qword ptr [rip + 0x1b1c5a]
Enter: _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
[tid:0] 130 [0x638870]: endbr64
[tid:0] 131 [0x638874]: push r15
[tid:0] 132 [0x638876]: push r14
[tid:0] 133 [0x638878]: push r13
[tid:0] 134 [0x63887a]: mov r13, rdx
[tid:0] 135 [0x63887d]: push r12
[tid:0] 136 [0x63887f]: push rbp
[tid:0] 137 [0x638880]: push rbx
[tid:0] 138 [0x638881]: mov rbx, rdi
[tid:0] 139 [0x638884]: sub rsp, 0x38
[tid:0] 140 [0x638888]: lea r15, [rsp + 0x20]
[tid:0] 141 [0x63888d]: mov qword ptr [rsp], rsi
[tid:0] 142 [0x638891]: mov rsi, rdi
[tid:0] 143 [0x638894]: mov rdi, r15
[tid:0] 144 [0x638897]: call 0x59ff30
[tid:0] 145 [0x59ff30]: jmp qword ptr [rip + 0x1b104a]
Enter: _ZNSo6sentryC2ERSo
[tid:0] 146 [0x637ed0]: endbr64
[tid:0] 147 [0x637ed4]: push rbp
[tid:0] 148 [0x637ed5]: mov rbp, rdi
[tid:0] 149 [0x637ed8]: push rbx
[tid:0] 150 [0x637ed9]: mov rbx, rsi
[tid:0] 151 [0x637edc]: sub rsp, 8
[tid:0] 152 [0x637ee0]: mov rax, qword ptr [rsi]
[tid:0] 153 [0x637ee3]: mov qword ptr [rdi + 8], rsi
[tid:0] 154 [0x637ee7]: mov byte ptr [rdi], 0
[tid:0] 155 [0x637eea]: mov rdi, qword ptr [rax - 0x18]
WARNING:tritondse.executor:Memory violation: (4: 0xffffffffffffffe8 unmapped)

Thus the memory violation seems to be performed by the mov rdi, qword ptr [rax - 0x18] where rax is likely 0 for an unknown reason.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants