160 - 52 egis.1

环境:windows xp

工具:
1、OllyDBG
2、exeinfo
3、IDA

0x00 查壳
在这里插入图片描述

加了UPX壳,那么就要脱壳了。可以使用单步法来脱壳。

UPX壳还是比较简单的,开头pushad,找个popad,然后就是jmp了。
在这里插入图片描述

然后就可以用OD来脱壳了。

0x01 分析
先运行一下程序,看看有什么东西。
在这里插入图片描述

随便输入些东西进去,弹出了提示输入错误的消息框。

OD载入,F9运行程序。然后随便输入点东西,弹出上面找个消息框。在OD中按F12暂停,Alt+F9运行到用户代码,然后点击消息框的确定。

程序停在这里
在这里插入图片描述

单步执行到函数返回。
在这里插入图片描述

记下这个401E86,然后在IDA打开这个脱壳后的程序。等待IDA分析完后,按G跳转,输入这个401E86
在这里插入图片描述

跳转完后就可以按F5进行分析了。
在这里插入图片描述
在这里插入图片描述

程序的流程主要如下:
一、程序根据输入的用户名进行处理:
(1)将输入的内容翻转再拼接一起,如输入:gnubd,将得到gnubddbung
(2)读取HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion下的ProductIDRegisteredOwner的值,并且拼接到第(1)步的结果后面。

二、然后再进行类似md5值的计算:
用 smd5(input_username_2) 表示结果。
程序再对输入的序列号进行运行,用 calc(input_serial) 表示结果。
由于smd5(input_username_2)的结果是4个DWORD,即smd5_result[4],所以第57行处要求用户的输入也是4个DWORD,所以这里对输入的内容进行了限制,为0-9,A-F,a-f这样。
calc(input_serial)的结果也是4个DWORD,即calc_result[4],接下来就是第68行处进行smd5_resultcalc_result 比较,全部相等就输出通过。

首先来分析一下这个smd5,我这里有个md5算法笔记,可以先看看普通md5的算法是怎样的。

看完之后比较这个程序的,可以发现是第54行处存在差异。填充后的消息在计算长度的时候把0x80也算上了,这样使得计算出来的值与普通的md5值不同,这个写出代码的难度不大,找个md5源码改一下就行了。

三、接下来看一看calc函数,也就是地址sub_401B90处的函数。

int __cdecl sub_401B90(int input_0, int constValue)
{int result; // eax@1int v3; // ebx@1unsigned int first; // esi@1unsigned int second; // edi@1unsigned __int64 v6; // rax@2int v7; // esi@2int v8; // edi@2unsigned __int64 v9; // rax@2result = input_0;v3 = constValue;first = *(_DWORD *)input_0; //输入的第一个值second = *(_DWORD *)(input_0 + 4);//输入的第二个值if ( constValue ){do{v6 = 2 * __PAIR__(second, first);         // 这里注意可能存在 first<<1 发生进位,而 second<<1 丢失第31位LODWORD(v6) = ((unsigned __int8)(2 * first) | (second >> 31)) & 4;v7 = v6 | (second >> 31);v8 = HIDWORD(v6);                         // second<<1 | first>>31v9 = (unsigned __int64)(unsigned int)v6 << 11;// 第3位移动到了第14位LODWORD(v9) = v7 & 0x2000 ^ v9;v9 <<= 18;                                // 第14位移动到32位LODWORD(v9) = v7 & 0x80000000 ^ v9;v9 *= 2i64;                               // 将结果移动到了高32位的最后1位first = v9 ^ v7;second = HIDWORD(v9) ^ v8;--v3;}while ( v3 );result = input_0;}*(_DWORD *)result = first;*(_DWORD *)(result + 4) = second;return result;
}

因为上面是由ida分析得到的,v6和v9这些事int64类型的变量,分析起来可能比较难,所以为了简单理解,我将其拆分,v6的高32位为v6_h,v6低32位为v6_l,v9同理。

    do{v6_l = first<<1;         v6_h = second<<1 | first>>31;v6_l = first<<1 & 4 ; // 因为有个&4,所以找个second>>31可以忽略了,不影响结果v7 = v6_l | (second >> 31); // first<<1 | (second >> 31)v8 = v6_h;          // second<<1 | (first >> 31)v9_l = v6_l << 11; // (first<<1 & 4)<<11v9_h = v6_l >> 21; // 0v9_l = v7 & 0x2000 ^ v9; // (first<<1 & 0x2000)^(first<<1 & 4)<<11v9_l <<= 18; // ((first<<1 & 0x2000)^(first<<1 & 4)<<11)<<18v9_h <<= 18; //0v9_l = v7 & 0x80000000 ^ v9;  //(first<<1 & 0x80000000) ^((first<<1 & 0x2000)^(first<<1 & 4)<<11)<<18                                     v9_h = v9_l>>31; // & 0x80000000 后就只剩下最高1位了,左移1位就进入到了高32位的最低1位v9_l <<= 1; // & 0x80000000 后就只剩下最高1位了,左移1位就溢出了,变回0first = v9_l ^ v7; // 0 ^ (first<<1 | (second >> 31)) second = v9_h ^ v8;// ((first<<1 & 0x80000000) ^((first<<1 & 0x2000)^(first<<1 & 4)<<11)<<18)>>31 ^ (second<<1 | (first >> 31))--v3;}while ( v3 );

将输入的serial设为first,那么第一轮运算的结果为first_1,second_1,根据上面可得:

first_1 = v9_l ^ v7; // 0 ^ (first<<1 | (second >> 31))second_1 = v9_h ^ v8;// ((first<<1 & 0x80000000) ^((first<<1 & 0x2000)^(first<<1 & 4)<<11)<<18)>>31 ^ (second<<1 | (first >> 31))

用first.1表示first的第1位,first.32表示first第32位,
即:first.1 = first & 1,first.3 = first & 0x80000000。
根据上面可以逆推得到:

first = first_1>>1 | ((first_1.32 ^ first_1.14 ^ first_1.3^ second_1)&1)
second = first<<31 | (second_1>>1);

这个逆推得到的函数称为 rcalc,
所以只需将 rcalc(smd5(input_username)) 计算出来就好了。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/376305.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

玩转MySQL之Linux下的简单操作(服务启动与关闭、启动与关闭、查看版本)

小弟今天记录一下在Linux系统下面的MySQL的简单使用&#xff0c;如下&#xff1a; 服务启动与关闭 启动与关闭 查看版本 环境 Linux版本&#xff1a;centeros 6.6&#xff08;下面演示&#xff09;&#xff0c;Ubuntu 12.04&#xff08;参见文章末尾红色标注字体&#xff09; M…

实验八第二题

转载于:https://www.cnblogs.com/huangsilinlana/p/3411550.html

c++ boost多线程学习(一)

本次学习相关资料如下&#xff1a; Boost C 库 第 6 章 多线程&#xff08;大部分代码的来源&#xff09; Boost程序库完全开发指南 - 深入C“准”标准库 第三版 罗剑锋著 头文件&#xff1a; #include <stdio.h> #include <string.h> #include <boost\versio…

C#中什么是泛型

所谓泛型是指将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型。一种类型占位符&#xff0c;或称之为类型参数。我们知道一个方法中&#xff0c;一个变量的值可以作为参数&#xff0c;但其实这个变量的类型本身也可以作为参数。泛型允许我们在调用的时候再指定这…

敏捷自动化测试(1)—— 我们的测试为什么不够敏捷?

测试是为了保证软件的质量&#xff0c;敏捷测试关键是保证可以持续、及时的对软件质量情况进行全面的反馈。由于在敏捷开发过程中每个迭代都会增加功能、修复缺陷或重构代码&#xff0c;所以在完成当前迭代新增特性测试工作的同时&#xff0c;还要通过回归测试来保证历史功能不…

学习c++

目录 一 、 boost库&#xff1a; 1. 多线程 c boost多线程学习&#xff08;一&#xff09; 二 、数据库&#xff1a; 三、socket编程&#xff1a; c socket学习&#xff08;1.1&#xff09; c socket学习&#xff08;1.2&#xff09; c socket学习&#xff08;1.3&#x…

mysql5.6与mysql5.5不同

1.编译阶段 要明白with与without的区别&#xff0c;选项值分1和0&#xff0c;或者对应为on或off&#xff0c;代表支持与不支持&#xff1b;with的1&#xff08;on&#xff09;与without的0&#xff08;off&#xff09;是同样的&#xff0c;with的0&#xff08;off&#xff09;与…

c++ 基本排序算法学习

C实现排序算法 代码地址 vector<unsigned int> cVec; int nSize cVec.size();1 冒泡排序 算法思路&#xff1a; 每两两相邻的数值都会比较大小&#xff0c;前面比后面大的时候就交换位置&#xff0c;否则就不动。 代码&#xff1a; void BubbleSort() {//优化&#x…

ios 程序学习

马上着手开发iOS应用程序&#xff1a;五、提交应用与寻找信息 2013-01-11 15:36 佚名 apple.com 我要评论(0) 字号&#xff1a;T | T本文介绍了您已经学习完如何开发一个优秀的iOS应用之后&#xff0c;应该掌握的内容&#xff0c;包括将您的应用提交到App Store让其他人下载&am…

解决SimpleButton被移除后保持OVER状态

假设场景中有一SimpleButton叫testBtn,执行下面操作&#xff1a;1.鼠标移上testBtn&#xff0c; testBtn状态变为OVER2.移除testBtn&#xff0c;removeChild(testBtn)3.5秒后重新添加testBtn到场景此时&#xff0c;看见testBtn还是OVER状态。解决方法&#xff1a;1.记录testBtn…

c++ socket学习(1.1)

本文学习相关资料&#xff1a; C/C socket编程教程 环境&#xff1a;vs2015 源码&#xff1a;本文代码 windows 如何创建客户端与服务端通信&#xff1f; TCP&#xff1a; 服务端 在windows先告诉程序我们要使用哪个版本的winsock&#xff0c;成功调用了它才能继续下去 #…

c++ socket学习(1.2)

本文学习相关资料&#xff1a; C/C socket编程教程 环境&#xff1a;vs2015 源码&#xff1a;本文代码 windows 如何创建客户端与服务端通信&#xff1f; UDP&#xff1a; 这次就没什么客户端服务端好说了&#xff0c;UDP是没有无连接的 所以改叫接收端和发送端吧 接收端 …

js高级功能与高级需求、高级期待

http://www.cnblogs.com/leadzen/archive/2008/02/25/1073404.html 简单练习题&#xff1a;http://tieba.baidu.com/p/2189347922 ---------------------- scope链 闭包 Javascript属性prototype node.js metaprogramming AMD、CMD机制 http://www.makumo.com/js-modules-amd-c…

synchronized同步锁

在多线程的情况下&#xff0c;由于同一进程的多个线程共享同一片存储空间&#xff0c;在带来方便的同时&#xff0c;也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突&#xff0c;有效避免了同一个数据对象被多个线程同时访问。由于我们可以通过 private…

c++ socket学习(1.3)

本文学习相关资料&#xff1a; C/C socket编程教程 环境&#xff1a;vs2015 源码&#xff1a;本文代码 在这里c socket学习&#xff08;1.1&#xff09;学到了怎么样建立TCP&#xff0c;然后通过TCP连接发送、接收信息。 但是都是一次性的&#xff0c;当时是接收信息后就结束…

一个一线城市的IT白领的生活成本:3万/年

自从大学毕业&#xff0c;经济独立&#xff0c;就开始全面统计各种生活开支。仔细的去统计下&#xff0c;发现开销还是挺大的。 定理&#xff1a;开销越大&#xff0c;就意味着你每个月的收入必须越高。 三族鼎立节余族: 收入-开支 > 0月光族&#xff1a;收入-开支 0透支族…

android 编译共享ccache的缓存

1. android自带的ccache版本号(2.4版本号)过低&#xff0c;是无法支持以上的功能的&#xff0c;须要使用新版ccache。2. 最新的ccache请到http://ccache.samba.org/download.html下载3. 下载解压之后&#xff0c;在linux底下进入ccache文件夹&#xff0c;执行:./configure./mak…

一位软件工程师的6年总结

作者&#xff1a;成晓旭 “又是一年毕业时”&#xff0c;看到一批批学子离开人生的象牙塔&#xff0c;走上各自的工作岗位&#xff1b;想想自己也曾经意气风发、踌躇满志&#xff0c;不觉感叹万千……本文是自己工作6年的经 历沉淀或者经验提炼&#xff0c;希望对所有的软件工…

c++ socket学习(1.4)

本文学习相关资料&#xff1a; C/C socket编程教程 环境&#xff1a;vs2015 源码&#xff1a;本文代码 前面学到了TCP怎么循环发包&#xff0c;但是TCP连接的话会出现一个问题粘包。 TCP连接接收到的数据并不是马上读取到内存里面的&#xff0c;而是放在缓冲区&#xff0c;让…

mongodb中分页显示数据集的学习

mongodb中分页显示数据集的学习 这次继续看mongodb中的分页。首先依然是插入数据&#xff1a; 1&#xff09; db.Blog.insert( { name : "Denis", age : 20, city : "Princeton" } ) db.Blog.insert( { name : "Abe", age : 30, city : &quo…