我找到了一个小工具,它使用 ptrace 来单步执行来自执行另一个程序的分叉子指令:
http://pastebin.com/yHbkc0Je
这工作得很好。我得到了所有使用的指令的转储。我知道它没有以 setuid 权限运行,但无论如何它可能会对我有所帮助。现在我只需要一些东西来反汇编指令跟踪。
基于此的PoC ( https://gist.github.com/Samuirai/5217680 )。
/*
This tool was developed through the awesome community effort on reverseengineering.stackexchange.com
The Thread: http://reverseengineering.stackexchange.com/questions/98/how-can-i-analyse-an-executable-with-no-read-permission
Special thanks to:
+ igor-skochinsky who pointed at this Phrack article and gave the initial idea: http://www.phrack.com/issues.html?issue=63&id=12&mode=txt
+ gilles for his engagement and enthisiasm about this question and his code attempt
+ and all others who were involved
This new stackexchange reverseengineering community is F**KING AWESOME!!! <3
*/
#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <sys/syscall.h>
int main()
{
pid_t pid;
pid = fork();
if(pid == 0) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl("./bin", "./bin", NULL);
}
else {
int status;
struct user_regs_struct regs;
// single stepping until it reached the real code segment
while(1) {
wait(&status);
if(WIFEXITED(status))
break;
// get registers for the instruction pointer
ptrace(PTRACE_GETREGS, pid, NULL, ®s);
// strace ./bin
// brk(0) = 0x804a000
if(regs.eip>0x804a000)
{
printf("in code section at EIP=%lx\n",regs.eip);
unsigned int i;
// Dump code
for(i=0; i<0x1000; i+=4) {
long data = ptrace(PTRACE_PEEKTEXT, pid, regs.eip+i, 0);
printf("%lx",data);
}
}
// single step in child process
ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL);
}
}
return 0;
}
正如吉尔斯所指出的,您无法通过阅读/proc/<pid>/maps
来获取代码区域的地址,但我认识到它strace
有这么好的单行brk(0) = 0x804a000
。
我单步执行子进程,直到 EIP 接近这个值;然后,我转储 0x1000 字节。