• 外部函数接口 LibFFI


    FFI” 的全名是 Foreign Function Interface,通常指的是允许以一种语言编写的代码调用另一种语言的代码。而 “Libffi” 库只提供了最底层的、与架构相关的、完整的”FFI”,因此在它之上必须有一层来负责管理两种语言之间参数的格式转换。

    高级语言编译器产生代码时都会依据一系列的规则,这些规则十分必要,特别是对独立编译来说。其中之一是“调用约定” (Calling Convention),它包含了编译器关于函数入口处的函数参数、函数返回值的一系列假设。它有时也被称作“ABI”(Application Binary Interface)。调用约定(Calling Conventions)定义了程序中调用函数的方式,它决定了在函数调用的时候数据(比如说参数)在堆栈中的组织方式。

    通常来说函数调用要用到的两条基本的指令:”CALL”指令和”RET”指令。”CALL”指令将当前的指令指针(这个指针指向紧接在CALL指令后面的那条指令)压入堆栈,然后执行一条无条件转移指令转移到新的代码地址。”RET”是与”CALL”指令配合使用的指令,在绝大多数函数中它是最后一条指令。”RET”指令弹出返回地址(就是早些时候”CALL”指令压入堆栈的地址)并将其加载到”EIP”寄存器中,然后从这个地址开始继续执行。

    图1-1 说明调用约定”stdcall”的调用过程,调用时,最末一个参数最先压入堆栈,而由被调用函数使用RET指令清栈。RET指令带有一个操作数,该操作数指明在EIP跳回主要函数之前需要释放的堆栈空间的字节数。这就是说,stdcall调用约定中RET指令带的操作数往往就意味着函数一共传入几个参数。

    calltype stdcall

    图1-1 stdcall调用

    独立编译时,调用一个函数除了要知道函数的签名外,还要知道其调用约定。比如 Delphi 中调用”Stdcall”的”VC++”的函数,需对调用约定加以声明。

    Procedure ShowMess (h :HWND; mess :PChar ); Stdcall; external LibName;

    LibFFI”针对这些不同的调用约定,提供一个高层次的可移植的API,只需调用这些API就可以在运行时进行动态的函数调用。(这种方式和函数指针不同,函数指针比如在编译时就决定了函数的类型,而”libffi”可以在运行时是才决定被调用函数的类型)。有了 libffi ,我们就有可能写出一个通用而且简洁的调用 C 函数的方法。

    目前有许多项目都使用了 libff ,包括 ruby,cpython, openjdk,dalvik vm 等等。例如在 Ruby 中,利用 rubyffi (包装了 libffi )可以如此动态地调用一个 dll

    https://www.oschina.net/p/libffi

  • 相关阅读:
    A题
    CTF--web BugKu-ctf-web(1-10)
    CTF--web 攻防世界web题 robots backup
    CTF--web 攻防世界web题 get_post
    BUUCTF-Crypyo-No.1
    攻防世界-新手篇(Mise)~~~
    BJDCTF-2020-WRITEUP---TiKi小组
    TKCTF-学校内部的校赛
    BUUCTF-BJD(更新V1.0)
    线程池(1)-参数
  • 原文地址:https://www.cnblogs.com/feng9exe/p/10396313.html
Copyright © 2020-2023  润新知