發表文章

目前顯示的是 4月, 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

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

圖片
近日很少發發廢文啊XD,大學生各種忙碌期中考 最近觀書有感,來發發拆拆手札廢文 參考文獻 緩衝區溢位攻擊:第三章 - 改變程式執行的行為 MSDN - PEB structure MSDN -  RTL_USER_PROCESS_PARAMETERS structure MSDN - 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];

[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"; })); 又因為=>後面可接陳述塊或者陳述句,所

[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啦)

[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)如果一樣就返回破解成功 所以我