keystone-engine / keystone

Keystone assembler framework: Core (Arm, Arm64, Hexagon, Mips, PowerPC, Sparc, SystemZ & X86) + bindings
http://www.keystone-engine.org
GNU General Public License v2.0
2.3k stars 458 forks source link

keystone is bad supporting X86 when resolving PCRel. #574

Open bbqz007 opened 10 months ago

bbqz007 commented 10 months ago
    // A number of ARM fixups in Thumb mode require that the effective PC
    // address be determined as the 32-bit aligned version of the actual offset.
    if (ShouldAlignPC) Offset &= ~0x3;
    Value -= Offset;

in arm platform, relating to the beginnig of bl or bx, it may be right.

but in x86 platform, it needs relating to the end of call or jmp, keystone must be totally wrong.

so, there is no choice except rebuilding custom binary by modifying the codes, if you need to use it in x86 platform.

bbqz007 commented 10 months ago

there is freak

if (Sym.isDefined()) {
      Value += Layout.getSymbolOffset(Sym, valid);
      if (!valid) {
        KsError = KS_ERR_ASM_FIXUP_INVALID;
        return false;
      }

the value is offset -4 where the actual location

} else {
        // a missing symbol. is there any resolver registered?
        if (KsSymResolver) {
            uint64_t imm;
            ks_sym_resolver resolver = (ks_sym_resolver)KsSymResolver;
            if (resolver(Sym.getName().str().c_str(), &imm)) {
                // resolver handled this symbol
                Value = imm;
                IsResolved = true;

where we return the location of resolved symbol,

that maybe the real problem.

when Symbol is defined, the Value is a shift -4 to the actual location, and the resolver we do return a no shift actual location.

so, the PCRel needs a shift -4 value, the resolver by us can not meets it.