C中复杂的变量赋值(反编译的ELF)
Complicated variable assignment in C (decompiled ELF)
所以我必须获得“隐藏”在此处某处的密码
void __regparm3 entry(undefined4 param_1,void *param_2,size_t param_3,void *param_4,size_t param_5)
{
char cVar1;
int iVar2;
size_t __n;
void *__buf;
int unaff_retaddr;
_write((int)prompt,param_2,param_3);
_read(unaff_retaddr,param_4,param_5);
iVar2 = 0;
do {
cVar1 = (**(code **)(&vfunc + (uint)(byte)(&vmp)[iVar2] * 4))(); //cant understand this
if (cVar1 != (&vmr)[__n]) {
_write((int)fail,__buf,__n);
/* WARNING: Subroutine does not return */
_exit(unaff_retaddr);
}
iVar2 = __n + 1;
} while (iVar2 != 0x17);
_write((int)success,__buf,0x17);
/* WARNING: Subroutine does not return */
_exit(unaff_retaddr);
}
我发现 vmr 包含 0x17 个值而 vmp 只有一个:03。
问题:
cVar1 是如何创建的,尤其是这个 (**(code **)(&vfunc + (uint)(byte)(&vmp)[iVar2] * 4))()
是什么意思?此行是将 vmp 值转换为某个数字还是其他什么?
这是对由 索引 函数指针引用的函数的调用,返回的内容随后存储到 char
变量中但是:
- 似乎是故意混淆的;
- 这个表达式中隐含的一些变量明显地在我们在这里看到的代码示例之外声明。
但是无论如何,这里的表达式是这样说的:
vfunc
可能是一个 32 位整数数组,就像指向不同回调函数的指针一样,没有被显式声明为指针(可能由于某些长度和格式目的);
vmp
可能是一个数组,其中包含每个特定情况下要调用的函数的编号;
&vmp
returns 这个数组的地址(如果这真的是一个数组就没用了,如果是 union
什么的就可能是必需的);
&vmp[iVar]
获取由 iVar
索引的条目的值;
(uint)(byte)
然后首先将此值转换为一个字节(可能是为了修剪不必要的位),然后再转换为一个整数。请注意,强制转换运算符优先级 (…)
位于索引 […]
之后;
- 由于 32 位指针,此索引乘以
* 4
,这往往表示 vfunc
不指向本机声明的指针,否则指针算法将适用;
- 如此获得的指针被强制转换为
(code **)
,这是一个“指向某些代码的指针”。 code
这里可能是用 typedef
; 声明的函数指针的别名
- 此指针被取消引用两次以访问函数本身:
(** …)
- 通过附加最后一个括号
…()
; 调用此函数(不带参数)
- 这个函数的这个结果赋值给 cVar1 :
cVar1 = …
所以我必须获得“隐藏”在此处某处的密码
void __regparm3 entry(undefined4 param_1,void *param_2,size_t param_3,void *param_4,size_t param_5)
{
char cVar1;
int iVar2;
size_t __n;
void *__buf;
int unaff_retaddr;
_write((int)prompt,param_2,param_3);
_read(unaff_retaddr,param_4,param_5);
iVar2 = 0;
do {
cVar1 = (**(code **)(&vfunc + (uint)(byte)(&vmp)[iVar2] * 4))(); //cant understand this
if (cVar1 != (&vmr)[__n]) {
_write((int)fail,__buf,__n);
/* WARNING: Subroutine does not return */
_exit(unaff_retaddr);
}
iVar2 = __n + 1;
} while (iVar2 != 0x17);
_write((int)success,__buf,0x17);
/* WARNING: Subroutine does not return */
_exit(unaff_retaddr);
}
我发现 vmr 包含 0x17 个值而 vmp 只有一个:03。
问题:
cVar1 是如何创建的,尤其是这个 (**(code **)(&vfunc + (uint)(byte)(&vmp)[iVar2] * 4))()
是什么意思?此行是将 vmp 值转换为某个数字还是其他什么?
这是对由 索引 函数指针引用的函数的调用,返回的内容随后存储到 char
变量中但是:
- 似乎是故意混淆的;
- 这个表达式中隐含的一些变量明显地在我们在这里看到的代码示例之外声明。
但是无论如何,这里的表达式是这样说的:
vfunc
可能是一个 32 位整数数组,就像指向不同回调函数的指针一样,没有被显式声明为指针(可能由于某些长度和格式目的);vmp
可能是一个数组,其中包含每个特定情况下要调用的函数的编号;&vmp
returns 这个数组的地址(如果这真的是一个数组就没用了,如果是union
什么的就可能是必需的);&vmp[iVar]
获取由iVar
索引的条目的值;(uint)(byte)
然后首先将此值转换为一个字节(可能是为了修剪不必要的位),然后再转换为一个整数。请注意,强制转换运算符优先级(…)
位于索引[…]
之后;- 由于 32 位指针,此索引乘以
* 4
,这往往表示vfunc
不指向本机声明的指针,否则指针算法将适用; - 如此获得的指针被强制转换为
(code **)
,这是一个“指向某些代码的指针”。code
这里可能是用typedef
; 声明的函数指针的别名
- 此指针被取消引用两次以访问函数本身:
(** …)
- 通过附加最后一个括号
…()
; 调用此函数(不带参数)
- 这个函数的这个结果赋值给 cVar1 :
cVar1 = …