我是Linux和C的初学者。 我需要运行一个我下载的程序,在自述文件中编写了运行“make”来构建它的运行包。但是当我运行它时,我遇到了这些错误:
~/injectso-0.2$ make
gcc -I./ -c -g -O2 -Wall procdbg.c
procdbg.c: In function ‘push_stack_proc’:
procdbg.c:149:26: error: lvalue required as left operand of assignment
(unsigned long) pvEsp -= iSize;
^
procdbg.c: In function ‘restore_syscall’:
procdbg.c:244:49: error: lvalue required as left operand of assignment
(unsigned long) ptProcStatus->regs.eip = (unsigned long) ptProcStatus->regs.eip - 2;
^
make: *** [procdbg.o] Error 1
似乎转换是错误的并且将赋值的左手赋予除地址之外的值。这是第一个错误的实际代码:
void *pvEsp;
SProcStatus tProcStatus;
/* If there is no data to be pushed, exit */
if (!iSize)
return(0);
/* Get the current ESP */
read_status(&(tProcStatus));
pvEsp = (void *) SP(tProcStatus);
show_debug(3, "Current ESP is %p\n", pvEsp);
/* Now subtract the amount of space we need for the */
/* data to be pushed */
(unsigned long) pvEsp -= iSize;
我将故障线路更改为底部,但错误仍然存在:
(unsigned long *) pvEsp -= iSize;
你有什么建议吗? 我在VMware上有ubuntu 14.04 i686。
问题是通过Slugonamission答案中链接的补丁解决的:
- (unsigned long) pvEsp -= iSize;
+ pvEsp -= (unsigned long) iSize;
和
- (unsigned long) ptProcStatus->regs.eip = (unsigned long) ptProcStatus->regs.eip - 2;
+ ptProcStatus->regs.eip = (unsigned long) ptProcStatus->regs.eip - 2;
但对于想要了解更多有关问题的信息的人,我个人对此并不了解,但会向您展示完整的功能代码:
/* Write a saved eip into the remote process, this */
/* address must NOT be a valid page (i.e it MUST cause */
/* a segfault). For fun we use 0x41414140 (not 41414141 */
/* since its nice to have an aligned address) */
pvEip = (void *) 0x41414140;
#if OS_LINUX && CPU_IA32
push_stack_proc(&pvEip, sizeof(pvEip));
.....
/* push_stack_proc - Push specified data onto the remote */
/* stack */
void *push_stack_proc(void *pvAddr, int iSize) {
void *pvEsp;
SProcStatus tProcStatus;
/* If there is no data to be pushed, exit */
if (!iSize)
return(0);
/* Get the current ESP */
read_status(&(tProcStatus));
pvEsp = (void *) SP(tProcStatus);
show_debug(3, "Current ESP is %p\n", pvEsp);
/* Now subtract the amount of space we need for the */
/* data to be pushed */
pvEsp -= (unsigned long) iSize; //correct line
//((unsigned long ) pvEsp) -= iSize; //faulty line
/* Round it to a multiple of 8 (if it isn't already) */
/* (We use 8 since Sparc requires double word alignment) */
pvEsp = (void *) round_down((unsigned long) pvEsp, STACK_ALIGN);
/* Write the ESP to the process */
SP(tProcStatus) = (unsigned long) pvEsp;
if (!write_regs(&(tProcStatus)))
show_abort("Could not modify stack pointer in target process\n");
read_status(&(tProcStatus));
show_debug(3, "New SP is 0x%08x\n", SP(tProcStatus));
/* Now write the data itself to the remote process */
if (iSize > (write_proc(pvEsp, pvAddr, iSize)))
show_abort("Could not write to remote process\n");
return(pvEsp);
}
答案 0 :(得分:0)
不,你的解决方案会改变程序的语义(尽管在不知道isize
是什么或引用的情况下很难说哪个是正确的),例如。
int foo = 32;
foo = (unsigned long)foo - 5; // 27
foo = (unsigned long*)foo - 2; // will subtract 2*(sizeof(unsigned long*))
演员表的结果不是左值而且不能分配,应该重写,而不是强制转换为原始值,例如
pvEsp = (void*)((unsigned long)pvPsp - iSize);
在C中,可以省略对void*
的强制转换,并隐含在没有警告的情况下。
此外,Gentoo开发人员似乎有一个修复此问题的补丁,可在此处找到:https://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/dev-util/injectso/files/injectso-0.2-gcc4.patch
答案 1 :(得分:0)
从您的代码段和错误看起来iSize
是值而不是地址,而pvEsp
是地址。如下更改故障线,应解决编译错误 -
*(unsigned long *) pvEsp -= iSize;