假设我有一个动态链接的ELF二进制文件,我想覆盖/重定向某些库调用.我知道我可以这样做LD_PRELOAD,但我想要一个在二进制文件中永久存在的解决方案,独立于环境,并且适用于setuid/setgid二进制文件,其中没有一个LD_PRELOAD可以实现.
我想做的是从其他目标文件添加代码(如果需要,可能在新的部分中),并将这些目标文件中的符号添加到二进制符号表中,以便使用新添加的代码版本代替共享库代码.我相信这应该是可能的,而不需要在现有代码中实际执行任何重定位; 即使它们在同一个文件中,它们也应该能够在运行时以通常的PLT方式解析(因为我只关心函数而不是数据).
请不要给我答案"你不想这样做!" 或者"那不便携!" 我正在研究的是一种将二进制文件与稍微ABI不兼容的备用共享库实现连接起来的方法.有问题的平台是i386-linux(即32位),如果重要的话.除非我弄错了什么是可能的,否则我可以编写一些工具来解析ELF文件并执行我的黑客攻击,但我怀疑有一种奇特的方法可以使用GNU链接器和其他工具来完成此操作而无需编写新代码.
好的..所以我正在使用gdb在x86上进行调试.有问题的特定文件被剥离,所以我没有二进制本身的符号.我无法访问源代码,但大致了解了幕后发生的事情.
我的asm知识足以决定一个函数的用途并决定它的用途.因此,我可以在查看它们一段时间后决定我自己适当的函数名称,但我希望能够将它们作为符号注入,以便一旦确定它们就可以在以后的调试中使用.
有人知道如何将自定义符号加载到gdb中吗?我已经考虑重新编译gdb并向UI添加一个额外的命令以允许在地址处加载符号.我想知道是否可以使用我定义的符号创建一个虚拟对象文件,然后加载它使用add-symbol-file?或者是否可以编译带有虚函数的交流程序,那么如何强制它们在正确的大小和正确的位置,然后简单地加载?
因此x86-64具有RIP相对地址,这使得PIC代码易于编写,重定位所需的更少.为什么在x86-64上仍然需要重定位?有什么功能?我可以尝试探索objdump但是要编译哪些C/C++代码模式?
我有一个简单的C程序:
// it is not important to know what the code does you may skip the code
Run Code Online (Sandbox Code Playgroud)
main.c中
#include <bsp.h>
unsigned int AppCtr;
unsigned char AppFlag;
int SOME_LARGE_VARIABLE;
static void AppTest (void);
void main (void)
{
AppCtr = 0;
AppFlag = 0;
AppTest();
}
static void Foo(void){
SOME_LARGE_VARIABLE=15;
}
static void AppTest (void)
{
unsigned int i;
i = 0;
while (i < 200000) {
i++;
}
BSP_Test();
SOME_LARGE_VARIABLE=3;
Foo();
}
Run Code Online (Sandbox Code Playgroud)
bsp.c
extern int SOME_LARGE_VARIABLE;
extern unsigned char AppFlag; …Run Code Online (Sandbox Code Playgroud) 我有一个静态链接到libc的精灵二进制文件.我无法访问其C代码.我想使用OpenOnload库,它在用户空间中实现了套接字,因此与标准libc版本相比可以提供更低的延迟.OpenOnload实现标准套接字api,并使用LD_PRELOAD覆盖libc版本.但是,由于此elf二进制文件是静态链接的,因此无法使用套接字API的OpenOnload版本.
我相信可以通过以下步骤将此二进制文件转换为与OpenOnload动态链接:
作为第一个剪辑,我尝试添加3个PT_LOAD段.在现有PT_LOAD段标头之后添加了新的段标头.此外,未修改现有段的vm_addr.基于p_align将现有段的文件偏移量下移到下一个对齐的地址.在文件末尾的文件中添加了新的PT_LOAD段.
在重新编写文件之后,当我运行它时,它被内核正确加载,但随后它立即发生了故障.
我的问题是:
我在String Table中找到了".dynsym",得到了索引.然后我找到了sh_name = index && sh_type = SHT_DYNSYM的节.所以我得到sh_offset = 464和sh_size = 64.但你可以在附图中看到,在偏移464上只有零.
我想导入表在偏移量528上开始.问题是:如何计算它%)
编译事实背后的理性是什么?
namespace ns __attribute__((visibility("default"))) {
template<typename T>
inline int func1(const T& x) {
return x;
}
inline int func2(int x) {
return x;
}
struct test {
template<typename T>
int func3(const T &x) { return x; }
int func4(int x) { return x; }
};
}
int __attribute__((visibility("default"))) client(int x) {
ns::test t;
const int y1 = ns::func1(x);
const int y2 = ns::func2(x);
const int y3 = t.func3(x);
const int y4 = t.func4(x);
return y1 + y2 + y3 + …Run Code Online (Sandbox Code Playgroud) 我想证明密码很容易从程序中读取:
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv)
{
char password[] = "a big refreshing lemonade";
return strcmp(argv[1], password);
}
Run Code Online (Sandbox Code Playgroud)
但是它不能按预期工作:
$ gcc foo.c
$ hexdump -C a.out | grep -C2 'lem'
000006c0 00 00 00 48 89 45 f8 31 c0 48 b8 61 20 62 69 67 |...H.E.1.H.a big|
000006d0 20 72 65 48 ba 66 72 65 73 68 69 6e 67 48 89 45 | reH.freshingH.E|
000006e0 d0 48 89 55 d8 48 b8 …Run Code Online (Sandbox Code Playgroud) 我试图制作一个在Contiki OS上运行的传感器,以执行新的二进制文件并替换当前的二进制文件(如果发生事件)。
我正在使用Cooja模拟器和Sky note,并且将二进制文件上传到节点的Coffee文件系统中(使用Cooja脚本),我想执行hello-world.ce
要编译我将动态加载模块的当前程序(reboot.c),我使用了以下命令:
对于将要加载的hello-world,我使用了:
这是我试图执行hello-world的代码(reboot.c)的一部分
#include "contiki.h"
#include "core/loader/elfloader.h"
#include "cfs/cfs.h"
PROCESS(hello_world_process, "Reboot process");
AUTOSTART_PROCESSES(&hello_world_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(hello_world_process, ev, data)
{
PROCESS_BEGIN();
int i;
int binFile,ret;
elfloader_init();
binFile=cfs_open("hello-world.ce",CFS_READ);
printf("cfs_open:%d\n",binFile); //returns 0 so the file is opened
ret=elfloader_load(binFile);
cfs_close(binFile);
printf("loader returned: %d\n",ret); //returns 0 ->meaning everything is ok
if(ret == ELFLOADER_OK){
printf("elf OK\n");
for(i=0; elfloader_autostart_processes[i] != NULL; i++) {
printf("exec: starting process …Run Code Online (Sandbox Code Playgroud) 我想学习elf文件,但是当我想到全局变量,全局静态变量和范围静态变量时,我有些困惑.例如:
int a = 2;
int b;
static int c = 4;
static int d;
void fun(){
static int e = 6;
static int f;
}
int main(void){
fun();
}
Run Code Online (Sandbox Code Playgroud)
谁能告诉每个变量属于哪个细分?在我看来,
b,d和f属于.bss段和a,c以及e属于数据段,但我不知道全局静态变量和ELF文件的全局变量之间的差异.
elf ×10
c ×5
linux ×4
gcc ×2
assembly ×1
binutils ×1
c++ ×1
contiki ×1
cygwin ×1
dwarf ×1
gdb ×1
import-table ×1
intel ×1
openonload ×1
relocation ×1
string ×1
symbols ×1
templates ×1
visibility ×1
x86-64 ×1