發表文章

目前顯示的是 四月, 2015的文章

[Windows][PE][ASM][CE]從PE架構到模組架構到暴力列舉模組找模組位置(如Kernel32.dll)

圖片
此篇內容接續著前一篇Blog文: 從PE架構淺談純組語撈出當前進程的映像路徑
最近都在看Buffer Overflow相關資料...所以這類型廢文比較多XD
就把一段一段覺得蠻重要的部份整理出來了

參考文獻
緩衝區溢位攻擊:第三章 - 改變程式執行的行為MSDN - PEB structure
一樣先偷偷引用一下文章中的結構:
typedef struct _TEB { NT_TIB Tib;//0x00 PVOID EnvironmentPointer;//0x01c CLIENT_ID Cid;//0x20 PVOID ActiveRpcInfo;//0x28 PVOID ThreadLocalStoragePointer;//0x2c PPEB Peb;//0x30 ULONG LastErrorValue; ULONG CountOfOwnedCriticalSections; PVOID CsrClientThread; PVOID Win32ThreadInfo; ULONG Win32ClientInfo[0x1F]; PVOID WOW32Reserved; ULONG CurrentLocale; ULONG FpSoftwareStatusRegister; PVOID SystemReserved1[0x36]; PVOID Spare…

[Windows][PE][ASM][CE]從PE架構淺談純組語撈出當前進程的映像路徑

圖片
近日很少發發廢文啊XD,大學生各種忙碌期中考
最近觀書有感,來發發拆拆手札廢文

參考文獻
緩衝區溢位攻擊:第三章 - 改變程式執行的行為MSDN - PEB structureMSDN -  RTL_USER_PROCESS_PARAMETERS structureMSDN - UNICODE_STRING structure 懶人包:
每個Process中都會存在一個TEB結構體
偷偷引用一下文章中的結構:
typedef struct _TEB { NT_TIB Tib;// Offset = 0x00 PVOID EnvironmentPointer; CLIENT_ID Cid; PVOID ActiveRpcInfo; PVOID ThreadLocalStoragePointer; PPEB Peb; ULONG LastErrorValue; ULONG CountOfOwnedCriticalSections; PVOID CsrClientThread; PVOID Win32ThreadInfo; ULONG Win32ClientInfo[0x1F]; PVOID WOW32Reserved; ULONG CurrentLocale; ULONG FpSoftwareStatusRegister; PVOID SystemReserved1[0x36]; PVOID …

[C#] Lambda花式應用噁爛寫法(跨UI委派秒幹、多線程處理...etc)

為啥會有這篇呢...因為最近寫太多C# 突然發現Lambda對程式碼減化太有幫助了=...=
為了怕哪天老人癡呆忘了這些噁心的花式寫法,就開一篇Blog文紀錄了

以前在寫多線程,可能得這麼寫:
void Func() {/*多線程要做的事情*/} //接著呼叫: Thread nThread = new Thread(Func); nThread.Start();
但今天用Lambda可以改寫:
Thread nThread = new Thread(() => {/*多線程要做的事情*/}); nThread.Start();
甚至在噁心點寫的寫法:
new Thread(() => {/*多線程要做的事情*/}).Start(); 簡單來說Lambda的形式可拆解成: ()是指你的函數參數列、然後可用=>代表你要接的Lambda陳述句/塊,最後用{}把事情包起來。 在來就是比較討厭的C#內要做跨UI線程操控UI上物件,會有跨UI安全性線程問題, 所以一般會額外寫個委派函數,然後請求UI Thread去處理這個委派函數請求,才能控制 這樣往往可能只用一兩次的委派函數,卻要占用一個篇幅去寫委派函數
先看看正常的跨UI委派寫法:
private delegate void nCallback(string ContentText); public void n(string ContentText) { if (this.InvokeRequired) { nCallback obj = new nCallback(n); this.Invoke(obj, new object[] { ContentText }); return; } this.Text = ContentText; } //調用時呼叫n("str")

就可以改寫成:
this.Invoke(new Action(() => { this.Text = "Str"; }));

又因為=>後面可接陳述塊或者陳述句,所以可以寫這樣:
this.…

[Wargame][IDA][Python][ASM][CE]交大Wargame01,用Python寫出序號機演算法(下集)

圖片
這篇接續著上一集:[Wargame][IDA][CE][OD][ASM]交大Wargame01,手拆題解

呃,本來想說其實解出來答案就好了
不過後來看木棍有發JavaScript的這支CrackMe的Keygen序號演算法(點此)
所以就乾脆順便筆記一下該怎麼拆出這支程式的序列演算法好了XD

首先,上一集中(?)我們有教過IDA+CE+OD的combo怎麼用的
這邊直接用到IDA內建其實也有靜態文字搜索功能,很快就能找到CRACKED字串
在這條地址上單擊進入該文字變數地址、很快就能透過引用鍵結找回上集我們用OD翻出來的判斷核心點

那麼上集中我們提到,dword_45B844內存中這個位置會保存著序列答案
那我們這次焦點就放在用IDA去分析它的演算法是怎麼計算出這個dword變數的值
滑鼠對著dword_45B844單擊,可以看這條內存的引用鍵結
可以很快地看到這個答案的引用鍵結只有兩條道路
上面那條路0x458760是序號機演算法時寫入的,下面那條路0x458800就是核心判斷點判斷的了,單擊sub_458760做跟蹤

很快的可以用IDA跟蹤到這個頁面上看到這個CrackMe的核心演算法在這裡了
那接下來就是分析它的序號機演算法是怎麼算序號的:
首先我注意到了dword_45B844答案保存點所有被寫入的過程就這些而已,那我們目光放在這段,從20行到33行就是所有的序號機演算過程

在第二十行上0x45B844答案變數被清空,接著v3被賦予sub_403A64(dword_45B840)
咦?看不懂v3的值是什麼嗎?好的那麼我們開Cheat Engine下斷點在呼叫sub_403A64的這個點上看看它在幹嘛吧 :)
下斷點在Offset = 0x587A8上,當call被呼叫時,可以看到傳入edi就是0x45B840,不過它上面用了mov eax,[edi](以值傳遞)
那會看到函數呼叫結果返回值(eax)為1。(這是當我設置Name = a的時候)
這時候我們可以嘗試把Name設置為題目的:“HelloWorld”看看
當Name設置為HelloWorld時回傳值為0x0A(10),這時我們可以知道原來sub_403A64函數用於計算該文字的長度有幾個字(也就是strlen啦)

不過你可能會問說你用IDA看sub_403A64的結果會是:
可以看到這個計算文字長…

[Wargame][IDA][CE][OD][ASM]交大Wargame01,手拆題解(上集)

圖片
首先這次這次的主角
至於為啥我要拆這個呢...因為有人不會解...正好問我T^T
這種類型的wargame我一直都不怎麼會解XD 就當作練習看看了

下載題目(點我點我)


那麼首先題目要求是這樣的,希望輸入一組Name跟對應的序列(要求必須都是數字的序列),如果這組序列跟Name有對應關係就會跳出破解成功,反之就跳出“Try Again!“
如上圖所示

那這個問題現在其實很明顯了,那我們該怎麼解呢...
首先,我的想法是先找出內存中的”Try Again!“的內存指針,找出誰引用它
那麼很快的開啟OllyICE的文字搜索引擎翻了一下就可以看到很敏感的三個文字在這
逆著DEBUG追回去可以看到:
看到這裡,找到了0x458800就是主要核心的文字判斷點了
針對你的序列跟名字作演算後對應判斷正不正確的核心點
所以我的直覺就是...阿不就把Try Again的邏輯跳掉就好了嗎(?)
一個正常的破解者都會想到的做法XDDDDD
淺顯易懂 直接Nop掉不就好了嗎~~關鍵點爆破 (Y)
不過很快地把答案交給問我的人 就被打槍惹

他說題目是:Name為HelloWorld時的Serial為多少?
踏馬德聽到這個就頭痛啊...( ゚д゚)
吃了顆普拿疼後把程式拖進IDA
這邊可以看一下這個核心判斷點在幹嘛...
可以專注在 sub_407774(v10, v4) == dword_45B844這個,這邊是核心判斷序列到底正確不正確的位置,dword_45B844這個應該是前面做HASH時的存放點,拿來跟sub_407774()結果做比對,正確才會彈出破解成功

可以翻一下sub_407774在幹麻
再往內翻一層可以翻到sub_4037E8內,它對v11做什麼
它對傳入的文字每個數值做單一的xor運算(對v3)然後再把最後HASH結果去跟dword_45B844比對

你會發現TMD繞這麼一大圈其實它也在對序列做數值的xor一次做檢查而已
所以其實 sub_407774(v10, v4) == dword_45B844就不過是在比對使用者傳入的文字HASH後結果(sub_407774)跟該名字(HelloWorld)做HASH後的正確解答(dword_45B844)如果一樣就返回破解成功

所以我們可以把名字輸入HelloWorld然後用Cheat Engine抓一下
內存中dword_4…