首页
社区
课程
招聘
[旧帖] [分享]大智慧的公式密码算法(下) 0.00雪花
发表于: 2011-8-23 21:53 2306

[旧帖] [分享]大智慧的公式密码算法(下) 0.00雪花

2011-8-23 21:53
2306
感受风格:
一个程序是否优秀风格很重要,在看过大智慧的代码后,优秀这是我最先想到的赞美,虽然我已经基本不用大智慧来看股票,在来到论坛后被通达信界面的简洁明朗的风格吸引,基本上放弃了大智慧的使用,看代码并不影响看股票软件的选择~~:)
对于相对于通达信的内存泄漏,大智慧这方面无疑要优秀的多;
在读他的代码中的异常抛出,new 后必定有 delete,极少的全局变量,都说明是也非常规范的程序设计;

好了废话不说了,现在我们开始展开算法的跟踪和阅读;

在开始我们就用了sub_54F555来说这是按修改按钮后进入的代码点,其实在这之前还有先于它执行的,但对算法本身来说我们选择了省略,看来这是一错误的决定,因为我们现在必须要知道:(,好吧它之前被执行的顺序是:
sub_5516F5  sub_6DA0E5 sub_50B8AD sub_54F555

int __cdecl sub_54F555(int a1, void *a2, int a3);这个函数传递进来的参数是什么,在反相调试中很多时候参数的数据类型我们不必太讲究,本身C语言很多时候的数据类型是可以换转的,对于这种现象不再刻意说明,只要明白他们的原理即可;

那么此时利用IDA的图很容易找到他的上一层sub_50B8AD,如图所示:

.text:0050B90D                 push    edi             ; Buf1
.text:0050B90E                 call    sub_548EC9
.text:0050B913                 mov     ebx, eax
.text:0050B915                 pop     ecx
.text:0050B916                 test    ebx, ebx
.text:0050B918                 jz      loc_50BA9E
.text:0050B91E                 test    dword ptr [ebx+4], 1000h
.text:0050B925                 jnz     loc_50BA9E
.text:0050B92B                 cmp     dword_A512D8, 5
.text:0050B932                 jge     short loc_50B943
.text:0050B934                 mov     ecx, ebx
.text:0050B936                 call    sub_549941
.text:0050B93B                 test    eax, eax
.text:0050B93D                 jnz     loc_50BA9E
.text:0050B943
.text:0050B943 loc_50B943:                             ; CODE XREF: sub_50B8AD+85j
.text:0050B943                 and     dword ptr [esi+0E0h], 0
.text:0050B94A                 push    ebx
.text:0050B94B                 lea     ecx, [esi+0E4h]
.text:0050B951                 call    sub_54D1EA
.text:0050B956                 lea     eax, [esi+1ABh]
.text:0050B95C                 push    eax             ; a3
.text:0050B95D                 lea     eax, [esi+1AFh]
.text:0050B963                 push    eax             ; a2
.text:0050B964                 push    ebx               ; a1
.text:0050B965                 call    sub_54F555      ; 公式管理器"算法"验证
.text:0050B96A                 add     esp, 0Ch
.text:0050B96D                 test    eax, eax
.text:0050B96F                 jz      loc_50BA9E

在这段代码中call    sub_54F555 前有三个push 按照从右到左的参数入栈规则 前两个是公式列表框的数据(this)数据从控件中获取,最后一个是下面代码中作为KEY来用的a1,那么a1从什么地方来是什么?看下下面的代码
int __cdecl sub_548EC9(char *Buf1)
{
  char *v1; // esi@1

  v1 = Buf1;
  if ( memcmp(Buf1, "IND-", 4u) )
  {
    if ( memcmp(Buf1, "EXP-", 4u) )
    {
      if ( memcmp(Buf1, "SYS-", 4u) )
      {
        if ( !memcmp(Buf1, "CLR-", 4u) )
          v1 = Buf1 + 4;
      }
      else
      {
        v1 = Buf1 + 4;
      }
    }
    else
    {
      v1 = Buf1 + 4;
    }
  }
  else
  {
    v1 = Buf1 + 4;
  }
  return sub_5484EE(v1);
}

int __stdcall sub_5484EE(int a1)
{
  int v2; // eax@1

  v2 = CMapStringToOb__Lookup(a1, &a1);
  return v2 != 0 ? a1 : 0;
}

哦,原来是用CMapStringToOb::Lookup 查找到的含下列关键字的映射 IND- EXP- SYS-  !CLR- 并将返回的值

嗯,第一个关键点找到来源了,先暂时标记下,然后看看其他地方吧

前文说到int __cdecl sub_54F555(int a1, void *a2, int a3)中的参数A1很重要;

在通过CMapStringToOb::Lookup找到了A1目标地址后接下来我们看看他们又干了些什么,口令起到了什么作用

先上个图刺激下老师同学们,省得说KEY不知道在哪里~:)



如图在通过CMapStringToOb::Lookup找到了目标的地址是06322978(这个地址只对这次有效就不用特意知道为什么了),反正大智慧已经告诉我们是可以用CMapStringToOb::Lookup找到目标的,今后有大师想搞个遍历的公式XX的,不用想按照大智慧的法子去就行了;

在图中我们知道了063222978是我们反相出的A1参数,也指出过关键点是:

if ( sub_54952D(v12) == *(_DWORD *)(*(_DWORD *)(a1 + 155) + 4) )
        break;
      v13 = (const char *)ATL__CSimpleStringT_char_1___operator char_const__(&v20);
      if ( sub_549574(v13) == *(_DWORD *)(*(_DWORD *)(a1 + 155) + 4) )
        break;

A1 = 06322978h
那么

A1+ 155 = 06322A13h(A1+9Bh = 06322A13h)

他的内容是 78 2A 32 06 也就是 06322A78h

地址06322A78h + 4h   指向的地址内容是 F4 1C 46 06

比较的关键值是 EAX == 06322A78 + 4 指向的值

如果相同表示密码正确  ~~:) 哈是不是很简单?

在密码学中,如果有明文是,并且明文是可逆的那么设明文为 A 设加密后的密文为 M 
加密的函数 M= D(A)
解密的函数 W= S(M)

必然 A=S(M)=S(D(A))
A=S(D(A))

int __cdecl sub_4611CA(int a1, int a2, int a3, signed int a4, int a5) 为什么被多次调用,验证密码和解码的时候它在做什么?

补充内容:

1,搞一个最简单的公式,并且只有一个公式
2,加密码,以后每次都用相同密码
3,保存文件,备份他,再比较他看每次加密和不加密,以及不同时间加密之间有什么变化,注意用相同内容和相同密码,看他们的变化;如果有足够的能力也可以直接阅读代码;
4,看进入int __cdecl sub_54F555(int a1, void *a2, int a3)前A1指向的那片区域内容,不同的有密码和无密码做比较,多次比较;
5,观察在比较密码阶段int __cdecl sub_4611CA(int a1, int a2, int a3, signed int a4, int a5)和密码正确阶段,传递的值和返回的值

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 153
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
感谢楼主分享
2011-8-24 08:09
0
雪    币: 116
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
搞出收费公式来
2011-8-24 08:10
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢楼主!
2016-1-14 11:30
0
游客
登录 | 注册 方可回帖
返回
//