编译错误:左值作为赋值的左操作数所需的左值

时间:2016-02-28 14:39:17

标签: c

我是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);
}

2 个答案:

答案 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;