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.pswp.cn/news/376305.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/376305.shtml
英文地址,請注明出處:http://en.pswp.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…