相关疑难解决方法(0)

欺骗应用程序认为它的标准输出是一个终端,而不是管道

我正试图做相反的事情

检测stdin是终端还是管道?

我正在运行一个正在更改其输出格式的应用程序,因为它检测到stdout上的管道,我希望它认为它是一个交互式终端,以便在重定向时获得相同的输出.

我当时认为将它包装在expect脚本中或使用proc_open()PHP中的它会这样做,但事实并非如此.

有什么想法吗?

bash terminal stdin pipe

137
推荐指数
7
解决办法
5万
查看次数

挂钩并替换已导出的ELF中的导出功能(.so共享库)

我正在编写一些C代码,以挂接加载到内存中的.so ELF(共享库)的某些功能。

我的C代码应该能够重定向另一个已加载到应用程序/程序的内存中的.so库的导出函数。

这里有一些阐述:

在此处输入图片说明

Android应用将加载多个.so文件。我的C代码必须浏览属于另一个共享.so库(在本例中称为target.so)的导出功能

这不是常规的dlsym方法,因为我不仅想要函数的地址,而且想用自己的功能替换它;这样做的方式是:当另一个库调用其自己的函数时,将改为调用我的hook_func,然后从我的hook_func中调用原始函数。

对于导入功能,这可以工作。但是对于导出功能,我不确定该怎么做。导入函数的符号表中的条目在重定位表中具有相应的条目,这些条目最终给出了全局偏移表(GOT)中的条目地址。但是对于导出函数,符号的st_value元素本身具有过程的地址,而不具有GOT地址(如果我错了,请纠正我)。

如何执行导出功能的挂钩?

从理论上讲,我应该获取导出功能st_value的动态符号表项(Elf32_Sym)元素的存储位置。如果得到该位置,则应该可以用我的hook_func的地址替换该位置中的值。但是,到目前为止,我无法写入该位置。我必须假设动态符号表的内存是只读的。如果是这样,那该怎么办?

非常感谢您的阅读和帮助。

更新: LD_PRELOAD只能用我自己的函数替换原始函数,但是然后我不确定是否有任何方法可以调用原始函数。以我为例:

应用程序通过调用来初始化音频引擎Audio_System_Create,并将AUDIO_SYSTEM对象的引用传递给Audio_System_Create(AUDIO_SYSTEM **); AUDIO API,以分配此struct / object和函数返回。现在,只要我可以访问该AUDIO_SYSTEM对象,就可以轻松地向该对象附加一个回调并开始接收音频数据。因此,我的最终目标是获得对AUIOD_SYSTEM对象的引用。根据我的理解,只有在我第一次通过分配该对象的地方拦截该调用时,我才能得到该信息Audio_System_Create(AUIOD_SYSTEM **)。当前没有直接的方法来在android上获取输出音频。(所有示例都谈到仅录制来自麦克风的音频)

Update2: 正如Basile在他的回答中所建议的那样,我使用了dladdr(),但奇怪的是它给了我与传递给它相同的地址。

void *pFunc=procedure_addr;  //procedure address calculated from the st_value of symbol from symbol table in ELF file (not from loaded file)

        int  nRet;

            // Lookup the name of the function given the function pointer
            if ((nRet = dladdr(pFunc, &DlInfo)) != 0)
            {
                LOGE("Symbol …
Run Code Online (Sandbox Code Playgroud)

c linux shared-libraries elf symbol-table

3
推荐指数
1
解决办法
2264
查看次数

标签 统计

bash ×1

c ×1

elf ×1

linux ×1

pipe ×1

shared-libraries ×1

stdin ×1

symbol-table ×1

terminal ×1