首页
社区
课程
招聘
[结贴] 关于asmjit 代码重定位问题
发表于: 2018-10-11 23:12 4486

[结贴] 关于asmjit 代码重定位问题

2018-10-11 23:12
4486

新版本的重定位区说明
 // --------------------------------------------------------------------------
  // [Relocations]
  // --------------------------------------------------------------------------

  //! Create a new relocation entry of type `type` and size `size`.
  //!
  //! Additional fields can be set after the relocation entry was created.
  ASMJIT_API Error newRelocEntry(RelocEntry** dst, uint32_t type, uint32_t size) noexcept;

  //! Get if the code contains relocations.
  ASMJIT_INLINE bool hasRelocations() const noexcept { return !_relocations.isEmpty(); }
  //! Get array of `RelocEntry*` records.
  ASMJIT_INLINE const ZoneVector<RelocEntry*>& getRelocEntries() const noexcept { return _relocations; }

  ASMJIT_INLINE RelocEntry* getRelocEntry(uint32_t id) const noexcept { return _relocations[id]; }

  //! Relocate the code to `baseAddress` and copy it to `dst`.
  //!
  //! \param dst Contains the location where the relocated code should be
  //! copied. The pointer can be address returned by virtual memory allocator
  //! or any other address that has sufficient space.
  //!
  //! \param baseAddress Base address used for relocation. `JitRuntime` always
  //! sets the `baseAddress` to be the same as `dst`.
  //!
  //! \return The number bytes actually used. If the code emitter reserved
  //! space for possible trampolines, but didn't use it, the number of bytes
  //! used can actually be less than the expected worst case. Virtual memory
  //! allocator can shrink the memory it allocated initially.
  //!
  //! A given buffer will be overwritten, to get the number of bytes required,
  //! use `getCodeSize()`.
  ASMJIT_API size_t relocate(void* dst, uint64_t baseAddress = Globals::kNoBaseAddress) const noexcept;

这个问题主要是关于  X86Assembler  jmp()  立即数的使用问题
在之前的测试中,jmp 一个标签 ( Label )  一个寄存器( X86Gp ) 都是正常没有问题,但是jmp 一个立即数就没有值
测试代码:
 using namespace asmjit::x86;            // Easier access to x86/x64 registers.

    CodeHolder code;                        // Create a CodeHolder.
    code.init(CodeInfo(ArchInfo::kTypeX86));// Initialize it for a 32-bit X86 target.

                                            // Generate a 32-bit function that sums 4 floats and looks like:
                                            //   void func(float* dst, const float* a, const float* b)
    X86Assembler a(&code);                  // Create and attach X86Assembler to `code`.

    a.mov(eax, dword_ptr(esp, 4));          // Load the destination pointer.
    a.mov(ecx, dword_ptr(esp, 8));          // Load the first source pointer.
    a.mov(edx, dword_ptr(esp, 12));         // Load the second source pointer.

    a.movups(xmm0, ptr(ecx));               // Load 4 floats from [ecx] to XMM0.
    a.movups(xmm1, ptr(edx));               // Load 4 floats from [edx] to XMM1.
    a.addps(xmm0, xmm1);                    // Add 4 floats in XMM1 to XMM0.
    a.movups(ptr(eax), xmm0);               // Store the result to [eax].
    unsigned long addr = 0x401000;
    
    a.jmp(addr);
    a.ret();                                // Return from function.

                                            // Now we have two options if we want to do something with the code hold
                                            // by CodeHolder. In order to use it we must first sync X86Assembler with
                                            // the CodeHolder as it doesn't do it for every instruction it generates for
                                            // performance reasons. The options are:
                                            //
                                            //   1. Detach X86Assembler from CodeHolder (will automatically sync).
                                            //   2. Sync explicitly, allows to use X86Assembler again if needed.
                                            //
                                            // NOTE: AsmJit always syncs internally when CodeHolder needs to access these
                                            // buffers and knows that there is an Assembler attached, so you have to sync
                                            // explicitly only if you bypass CodeHolder and intend to do something on your
                                            // own.
    code.sync();                            // So let's sync, it's easy.

                                            // We have no Runtime this time, it's on us what we do with the code.
                                            // CodeHolder stores code in SectionEntry, which embeds CodeSection
                                            // and CodeBuffer structures. We are interested in section's CodeBuffer only.
                                            //
                                            // NOTE: The first section is always '.text', so it's safe to just use 0 index.
    CodeBuffer& buf = code.getSectionEntry(0)->getBuffer();

    // Print the machine-code generated or do something more interesting with it?
    for (size_t i = 0; i < buf._length; i++)
        printf("%02X", buf.getData()[i]);

输出结果:
8B4424048B4C24088B54240C0F10010F100A0F58C10F1100E900000000C3
//重定位后 
    VMemMgr vm;
    void* p = vm.alloc(code.getCodeSize());                    // Allocate a virtual memory (executable).
    if (!p) return 0;                                           // Handle a possible out-of-memory case.
    size_t realSize = code.relocate(p);                         // Relocate & store the output in 'p'.

输出结果:
8b4424048b4c24088b54240c0f10010f100a0f58c10f1100e9e30f3100c3  

问题已经解决,和老版本一样用,昨晚搞太晚迷糊了,两个参数填反了





[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2019-3-23 14:24 被Wszzy编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//