首页
社区
课程
招聘
[求助]这是什么类型的变量
发表于: 2015-10-15 08:55 4293

[求助]这是什么类型的变量

2015-10-15 08:55
4293
以下是IDA F5的一段代码:
  *((_QWORD *)this + 1) = 0LL; 变量

*((_BYTE *)this + 24) = 1;
  *v1 = -103;
  *(_BYTE *)(*((_QWORD *)this + 1) + 1LL) = -85;
  *(_BYTE *)(*((_QWORD *)this + 1) + 2LL) = -51;
  *(_BYTE *)(*((_QWORD *)this + 1) + 3LL) = -103;
  *(_BYTE *)(*((_QWORD *)this + 1) + (unsigned int)(*((_DWORD *)this + 4) + 4)) = -103;
  *(_BYTE *)(*((_QWORD *)this + 1) + (unsigned int)(*((_DWORD *)this + 4) + 5)) = -85;
  *(_BYTE *)(*((_QWORD *)this + 1) + (unsigned int)(*((_DWORD *)this + 4) + 6)) = -51;
  result = *((_QWORD *)this + 1);
  *(_BYTE *)(result + (unsigned int)(*((_DWORD *)this + 4) + 7)) = -103;

其中下面的赋值一半使用了间接地址赋值,请问这是一个什么类型的变量(红色字体)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 1491
活跃值: (980)
能力值: (RANK:860 )
在线值:
发帖
回帖
粉丝
2
数组or指针?
2015-10-15 10:41
0
雪    币: 115
活跃值: (23)
能力值: (RANK:20 )
在线值:
发帖
回帖
粉丝
3
指针取值,也就是取得地址,那么就应该是二级指针吧!拙见
2015-10-15 11:38
0
雪    币: 131
活跃值: (156)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hio
4
大量计算地址后赋值必定是结构体,这里又有this,应该是C++对象,structures建立个结构体,把V2转成这个结构体的指针,然后找到给v2构造的地方看new了多大,把结构体大小改成那个数
2015-10-15 12:49
0
雪    币: 131
活跃值: (156)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hio
5
另外这种强转多的地方最好把显示类型转换关掉
2015-10-15 12:50
0
雪    币: 18
活跃值: (26)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
非常感谢,我把帖子内容修改了一下,v2换成了this,红色字部分是类中的一个变量,现在猜测是结构体或者一个类的实例,不管是结构体或者类的实例,它的内部是什么样子的呢?这事疑惑所在。
2015-10-15 13:25
0
雪    币: 131
活跃值: (156)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hio
7
从赋值都从第二个地址开始赋值来看应该是个类的实例(对象),this指着的地方是指向虚表的指针,至于其它成员都是干什么的,什么结构,你得参照不同位置的引用慢慢猜,所以我建议你定义好structures然后慢慢分析

我写了一个简单的例子:
.text:00000000004008FF                 mov     edi, 18h        ; unsigned __int64
.text:0000000000400904                 call    __Znwm          ; operator new(ulong)
.text:0000000000400909                 mov     rbx, rax
.text:000000000040090C                 mov     rdi, rbx
.text:000000000040090F                 call    sub_400A50

这里new了0x18大小,先把结构体大小设好0x18:
00000000 class           struc ; (sizeof=0x18)
00000000 p_vtbl          dq ?
00000008                 db ? ; undefined
00000009                 db ? ; undefined
0000000A                 db ? ; undefined
0000000B                 db ? ; undefined
0000000C                 db ? ; undefined
0000000D                 db ? ; undefined
0000000E                 db ? ; undefined
0000000F                 db ? ; undefined
00000010                 db ? ; undefined
00000011                 db ? ; undefined
00000012                 db ? ; undefined
00000013                 db ? ; undefined
00000014                 db ? ; undefined
00000015                 db ? ; undefined
00000016                 db ? ; undefined
00000017 field_8         db ?
00000018 class           ends

接下来找找赋值的地方,推算各个成员的大小,像这样的:
__int64 __fastcall sub_4009B4(__int64 a1)
{
  __int64 result; // rax@1

  std::operator<<<std::char_traits<char>>(6295808LL, 4197131LL);
  *(_DWORD *)(a1 + 8) = 1;
  *(_BYTE *)(a1 + 12) = 99;
  result = a1;
  *(_QWORD *)(a1 + 16) = -81985529216486896LL;
  return result;
}

推算出成员大小:
00000000 class           struc ; (sizeof=0x18)
00000000 p_vtbl          dq ?
00000008 member1         dd ?
0000000C member2         dd ?
00000010 member3         dq ?
00000018 class           ends

然后F5里面把变量转成结构体指针:
class *__fastcall sub_4009B4(class *pobj)
{
  class *result; // rax@1

  std::operator<<<std::char_traits<char>>(6295808LL, 4197131LL);
  pobj->member1 = 1;
  LOBYTE(pobj->member2) = 99;
  result = pobj;
  pobj->member3 = -81985529216486896LL;
  return result;
}
class *__fastcall sub_400A50(class *a1)//这里是构造函数,给虚表赋值了
{
  class *result; // rax@1

  sub_400A3A();
  result = a1;
  a1->p_vtbl = (__int64)&off_400B30;
  return result;
}
__int64 sub_4008F6()
{
  class *pobj; // rbx@1

  pobj = (class *)operator new(0x18uLL);
  sub_400A50(pobj);
  sub_4009B4(pobj);
  (*(void (__fastcall **)(class *))pobj->p_vtbl)(pobj);//利用虚表调用虚函数
  return 0LL;
}
int __fastcall sub_4009F6(class *a1)//可以追踪到调用的虚函数是这个
{
  __int64 v1; // rbx@1
  __int64 v2; // rax@1
  __int64 v3; // rax@1

  v1 = a1->member3;
  LODWORD(v2) = std::operator<<<std::char_traits<char>>(0x601100LL, 0x400B0FLL);
  LODWORD(v3) = std::ostream::operator<<(v2, v1);
  return std::operator<<<std::char_traits<char>>(v3, 0x400B15LL);
}

基本上结构就很接近原程序了……原源码:
#include <iostream>
using std::cout;
using std::operator <<;

class base
{
	virtual void vfunc(){cout<<"base!\n";}
};
class classA : base
{
public:
	void func1(){cout<<"f1\n";a = 1;b = 'c';c = 0xfedcba9876543210;}
	virtual void vfunc(){cout<<"f2\nc="<<c<<"\n";}
private:
	int a;
	char b;
	unsigned long long c;
};
int main()
{
	classA *pobjA = new classA;
	pobjA -> func1();
	pobjA -> vfunc();
	
}
2015-10-15 16:53
0
雪    币: 18
活跃值: (26)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
谢谢,我好好看看,方便加个qq好友吗
2015-10-15 17:05
0
游客
登录 | 注册 方可回帖
返回
//