Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initializes PLT GOT in Primus (#993)
* initializes PLT GOT in Primus In BAP 2.0 we have a more conservative disassembler. And while previously, only the first instruction of a PLT entry was disassembled, now we're getting the whole entry. Unfortunately, the more precise disassembly hits analyses based on Primus. At least on x86/x86-64 targets. Previously, we got an unresolved call exception as soon as we enter a PLT entry, while now Primus follows to the whole chain of PLT resolution mechanism, like in the next example with call to free: ``` 400560: pushq 0x200aa2(%rip) # 601008 <_GLOBAL_OFFSET_TABLE_+0x8 400566: jmpq *0x200aa4(%rip) # 601010 <_GLOBAL_OFFSET_TABLE_+0x10> 40056c: nopl 0x0(%rax)<free@plt>: 400570: jmpq *0x200aa2(%rip) # 601018 <_GLOBAL_OFFSET_TABLE_+0x18> 400576: pushq $0x040057b: jmpq 400560 <_init+0x28>> ``` which does the following ``` 400576: increase the stack 40057b: jump to the very first plt entry 400560: increase the stack 400566: load the target from GOT tablek ``` Finally, at `400566` we're getting an unresolved call exception. And in the Primus promiscuous mode, we continue the execution. Here comes the crux of the problem, the stack is now broken: stack was increased twice and there wasn't any pop or ret instruction, so the following execution is wrong. The underlying problem is that the runtime function that performs lazy resolution of the PLT GOT entry is not stubbed and therefore the arguments that are passed to it via the stack are not popped. Probably the right solution would be to stub this function, but this is quite and involved process and it is not immediately obvious how to link it correctly (we do not know neither name nor an address). Another option, which is proposed in this PR, is to stop Primus from going that deep into the PLT entry by linking all GOT entries, by default, as unresolved. The ratification is simple -- if we got to the PLT entry, then the address wasn't linked, so there is no need to continue and we can raise an unresolved function asap. * removed unused code * checks memory is mapped before load for some reasons we don't get the whole got table with llvm 3.8 so we need to check is the memory is mapped before load * loads addresses directly from ".got.plt" section * use Memory.get instead of Interpreter * refactoring * removed unused code
- Loading branch information