我有一个为Linux开发的二进制程序,它从服务器的网络流中读取行。它的通信加密的方式需要我很长时间才能搞清楚,所以我无法重写它。
输出每一行后,程序调用{{1}}(我发现这是使用nanosleep(100000000)
)但是,当服务器快速连续发送多行时,实际流和输出之间有很大的延迟
由于我没有程序的源代码,我的问题是:有没有办法减少这个软件的睡眠时间? “加速”它?
作为参考,该计划是Punkbuster的PBUcon
答案 0 :(得分:4)
您可以尝试LD_PRELOAD技巧:
/* nosleep.c */
#include <time.h>
#include <unistd.h>
int sleep(unsigned int seconds)
{
return 0;
}
int usleep(useconds_t usec)
{
return 0;
}
int nanosleep(const struct timespec *req, struct timespec *rem)
{
return 0;
}
然后编译:
$ gcc -o libnosleep.so -shared nosleep.c -fpic
然后运行您的程序:
$ LD_PRELOAD=./libnosleep.so pbucon
您应该注意以下几点:
nanosleep
的每次调用,而不仅仅是您不喜欢的调用,并且可能会产生微妙的不良影响。如果您认为需要,可以检查参数的特定值。更新:如果要将呼叫链接到原始功能,可以执行以下操作:
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
int usleep(useconds_t sec)
{
typedef int (*usleep_f)(useconds_t);
static usleep_f real_usleep = NULL;
if (!real_usleep)
real_usleep = (usleep_f)dlsym(RTLD_NEXT, "usleep");
printf("%d\n", (int)sec);
if (...)
return real_usleep(sec);
else
return 0;
}
如果你想避免GNU扩展(RTLD_NEXT
是一个),你必须发现包含该函数的共享库的名称,例如:
$ objdump -p pbucon.run | grep NEEDED
NEEDED libc.so.6
然后,在函数中执行:
if (!real_usleep)
{
void *libc_so = dopen("libc.so.6", RTLD_GLOBAL);
real_usleep = (usleep_f)dlsym(libc_so, "usleep");
}
答案 1 :(得分:2)
不确定。我假设说话,因为我没有程序或来源,但nanosleep()
可能是通过调用sleep()
来表示的。如果是我,我会使用objdump -d
反汇编代码,看看我是否可以使用该代码和通过strace
获取的信息来查明对sleep()
(或其bvi
的具体调用变体),例如围绕它的调用等。这不是微不足道的,但是可能的。如果你能做到这一点,你可以看到传入了什么参数(在x86上,它们被推入堆栈;在64位上,它们将在寄存器中),然后直接修改它们。如果它们是变量,您也可以通过这种方式跟踪它们。
如果您找到要编辑的位置,为了实际编辑二进制文件,您可以使用xxd
之类的程序,甚至使用-r
输出文件,更改单词,以及然后使用其xxd
选项再次获取二进制文件。
编辑现在,objdump
中的偏移量与您在objdump
中看到的偏移量有所不同(我会忘记它是否始终如此)。这是因为xxd
中显示的偏移量是虚拟地址,readelf -WS
中显示的偏移量是文件中的实际偏移量。要协调此问题,您可以使用/bin/ls
来显示文件的标题标题,例如(以$ readelf -WS /bin/ls | grep .text
[13] .text PROGBITS 0000000000402460 002460 00c248 00 AX 0 0 16
为例):
PROGBITS
此处,相关信息是402460
之后的两列。 .text
是2460
部分的虚拟地址,这是存储二进制文件中可执行代码的位置,400000
是实际偏移量在文件中找到此部分的位置。减去这两个,你得到objdump
(当然是十六进制)。现在,如果你回到Disassembly of section .text:
0000000000402460 <close_stdout-0x6460>:
,你应该找到几行代码:
.text
所以你看到402460
从(404260 - 400000)
开始?在2460
或xxd
的文件中查找此功能(和数据),您应该找到它!所以你在{{1}}中寻找的是objdump中虚拟地址的位置减去你发现的偏移量,如上所述。很抱歉忘了这个!