日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

160 - 52 egis.1

發(fā)布時(shí)間:2023/12/1 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 160 - 52 egis.1 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

環(huán)境:windows xp

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

0x00 查殼

加了UPX殼,那么就要脫殼了。可以使用單步法來(lái)脫殼。

UPX殼還是比較簡(jiǎn)單的,開頭pushad,找個(gè)popad,然后就是jmp了。

然后就可以用OD來(lái)脫殼了。

0x01 分析
先運(yùn)行一下程序,看看有什么東西。

隨便輸入些東西進(jìn)去,彈出了提示輸入錯(cuò)誤的消息框。

OD載入,F9運(yùn)行程序。然后隨便輸入點(diǎn)東西,彈出上面找個(gè)消息框。在OD中按F12暫停,Alt+F9運(yùn)行到用戶代碼,然后點(diǎn)擊消息框的確定。

程序停在這里

單步執(zhí)行到函數(shù)返回。

記下這個(gè)401E86,然后在IDA打開這個(gè)脫殼后的程序。等待IDA分析完后,按G跳轉(zhuǎn),輸入這個(gè)401E86

跳轉(zhuǎn)完后就可以按F5進(jìn)行分析了。

程序的流程主要如下:
一、程序根據(jù)輸入的用戶名進(jìn)行處理:
(1)將輸入的內(nèi)容翻轉(zhuǎn)再拼接一起,如輸入:gnubd,將得到gnubddbung
(2)讀取HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion下的ProductIDRegisteredOwner的值,并且拼接到第(1)步的結(jié)果后面。

二、然后再進(jìn)行類似md5值的計(jì)算:
用 smd5(input_username_2) 表示結(jié)果。
程序再對(duì)輸入的序列號(hào)進(jìn)行運(yùn)行,用 calc(input_serial) 表示結(jié)果。
由于smd5(input_username_2)的結(jié)果是4個(gè)DWORD,即smd5_result[4],所以第57行處要求用戶的輸入也是4個(gè)DWORD,所以這里對(duì)輸入的內(nèi)容進(jìn)行了限制,為0-9,A-F,a-f這樣。
calc(input_serial)的結(jié)果也是4個(gè)DWORD,即calc_result[4],接下來(lái)就是第68行處進(jìn)行smd5_resultcalc_result 比較,全部相等就輸出通過(guò)。

首先來(lái)分析一下這個(gè)smd5,我這里有個(gè)md5算法筆記,可以先看看普通md5的算法是怎樣的。

看完之后比較這個(gè)程序的,可以發(fā)現(xiàn)是第54行處存在差異。填充后的消息在計(jì)算長(zhǎng)度的時(shí)候把0x80也算上了,這樣使得計(jì)算出來(lái)的值與普通的md5值不同,這個(gè)寫出代碼的難度不大,找個(gè)md5源碼改一下就行了。

三、接下來(lái)看一看calc函數(shù),也就是地址sub_401B90處的函數(shù)。

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; //輸入的第一個(gè)值second = *(_DWORD *)(input_0 + 4);//輸入的第二個(gè)值if ( constValue ){do{v6 = 2 * __PAIR__(second, first); // 這里注意可能存在 first<<1 發(fā)生進(jìn)位,而 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位移動(dòng)到了第14位LODWORD(v9) = v7 & 0x2000 ^ v9;v9 <<= 18; // 第14位移動(dòng)到32位LODWORD(v9) = v7 & 0x80000000 ^ v9;v9 *= 2i64; // 將結(jié)果移動(dòng)到了高32位的最后1位first = v9 ^ v7;second = HIDWORD(v9) ^ v8;--v3;}while ( v3 );result = input_0;}*(_DWORD *)result = first;*(_DWORD *)(result + 4) = second;return result; }

因?yàn)樯厦媸怯蒳da分析得到的,v6和v9這些事int64類型的變量,分析起來(lái)可能比較難,所以為了簡(jiǎn)單理解,我將其拆分,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 ; // 因?yàn)橛袀€(gè)&4,所以找個(gè)second>>31可以忽略了,不影響結(jié)果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位就進(jìn)入到了高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設(shè)為first,那么第一輪運(yùn)算的結(jié)果為first_1,second_1,根據(jù)上面可得:

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。
根據(jù)上面可以逆推得到:

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

這個(gè)逆推得到的函數(shù)稱為 rcalc,
所以只需將 rcalc(smd5(input_username)) 計(jì)算出來(lái)就好了。

總結(jié)

以上是生活随笔為你收集整理的160 - 52 egis.1的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。