EASYHOOK逆向寒假生涯(20/100)

拖进ida

在这里插入图片描述
第一眼猜测一下重要函数sub_401220sub_401240,看了一下sub_401240
在这里插入图片描述

很明显,不是,也就用来起浪费时间的作用。
再来看看sub_401220
在这里插入图片描述
这里搞的动作挺像那么回事的,动调一下看看

动调sub_401220

在这里插入图片描述
简单分析一下,

 v2 = GetCurrentProcessId();
  hProcess = OpenProcess(0x1F0FFFu, 0, v2);
  v0 = LoadLibraryA(LibFileName);
  *(_DWORD *)WriteFile_0 = GetProcAddress(v0, ProcName);

这四行代码就是为了获取dll文件中WriteFile的实际导入地址。计算机核心编程里会有详细讲解

 lpAddress = *(LPVOID *)WriteFile_0;

把地址值放在另外一个变量里面,后面会有用。

if ( !*(_DWORD *)WriteFile_0 )
    return sub_401370((int)&unk_40A044);

这是当失败的时候,这种地址的获取一般不会失败的,所以这里不用分析。

unk_40C9B4 = *(_DWORD *)lpAddress;

这里IpAddress的值是0x77361282,即WriteFile的实际地址值。然后把地址里的内容放在unk_40C9B4

 *((_BYTE *)&unk_40C9B4 + 4) = *((_BYTE *)lpAddress + 4);

&unk_40C9B4这里取出unk_40C9B4的地址,然后(_BYTE *)再把指针范围转变为一个字节,紧接着就是用0x77361282地址处的后4个字节的值 覆盖入(WriteFile起始地址+4)地址处,
(说白了也就是把WriteFile前五个字节的值暂存其它地方,下面等HOOK目的成功时,再来进行写回)
即从0x77361286地址处取处四个字节放在0x40C9B8(API的内容)中
在这里插入图片描述
在这里插入图片描述

之后再放一个E9指令,即Jmp

dword_40C9BD = (char *)sub_401080 - (char *)lpAddress - 5;

这行指令很熟悉吧?
跳转的目的地址- 跳转的起始地址- 指令长度

然后间接跳转就构成了。。紧接着把缓冲区里面的东西写入WriteFile
在这里插入图片描述
然后当调用WriteFile时,就来调用sub_401080这个函数喽,所以一切关键都在sub_401080函数身上,接下来我们就来看看:
在这里插入图片描述
在这里插入图片描述
这里也就是 HOOK成功之后,进行函数原值写回,然后再调用WriteFile
在这里插入图片描述

涉及加密的也就是sub_401000,紧接着来看看它

分析sub_401000

int __cdecl sub_401000(int a1, int a2)
{
    
    
  char i; // al
  char v3; // bl
  char v4; // cl
  int v5; // eax

  for ( i = 0; i < a2; ++i )
  {
    
    
    if ( i == 18 )
    {
    
    
      *(_BYTE *)(a1 + 18) ^= 0x13u;
    }
    else
    {
    
    
      if ( i % 2 )
        v3 = *(_BYTE *)(i + a1) - i;
      else
        v3 = *(_BYTE *)(i + a1 + 2);
      *(_BYTE *)(i + a1) = i ^ v3;
    }
  }
  v4 = 0;
  if ( a2 <= 0 )
    return 1;
  v5 = 0;
  while ( byte_40A030[v5] == *(_BYTE *)(v5 + a1) )
  {
    
    
    v5 = ++v4;
    if ( v4 >= a2 )
      return 1;
  }
  return 0;
}

代码不长,最主要要能看出Hook,如果没有仔细看,那么直接会陷入sub_401240无法自拔。。。

找出byte_40A030[v5]数组:

61 6A 79 67 6B 46 6D 2E  7F 5F 7E 2D 53 56 7B 38
6D 4C 6E 00

逆推上去

for ( i = 0; i < a2; ++i )
  {
    
    
    if ( i == 18 )
    {
    
    
      *(_BYTE *)(a1 + 18) ^= 0x13u;
    }
    else
    {
    
    
      if ( i % 2 )
        v3 = *(_BYTE *)(i + a1) - i;
      else
        v3 = *(_BYTE *)(i + a1 + 2);
      *(_BYTE *)(i + a1) = i ^ v3;
    }
  }

好了,接下来上 代码

#include <iostream>
using namespace std;
int main()
{
    
    
	unsigned char   a[] = {
    
    
		0x61, 0x6A, 0x79, 0x67 ,0x6B ,0x46 ,0x6D ,0x2E  ,0x7F ,0x5F ,0x7E ,0x2D ,0x53 ,0x56 ,0x7B ,0x38
,0x6D ,0x4C ,0x6E 
	};
	unsigned char b[19];
	unsigned char c;
	b[0] = a[0];
	for (int i = 0; i < 19; ++i) {
    
    
		if (i == 18) {
    
    
			b[i] = a[i] ^ 0x13;
		}
		else {
    
    
			c = a[i] ^ i;
			if (i % 2)
				b[i] = c + i;
			else
			{
    
    
				b[i + 2] = c;
			}
				
		}
	}

	for (int i = 0; i < 19; i++) {
    
    

		cout << b[i];
	}


}

在这里插入图片描述
b[0]这个位置有点问题,估计加密过程中哪里忘记考虑了,一猜就知道b[0]是f

flag{
    
    Ho0k_w1th_Fun}

猜你喜欢

转载自blog.csdn.net/CSNN2019/article/details/113855901
今日推荐