匯編代碼混淆
Ⅰ 匯編語言問題`基礎!高分
1
關系運算符的兩個操作數必須是數據,或是統一段內的兩個存儲單元的地址。進行關系運算後的比較操作後,結果是一個數值,若輸出為0 ,則是0FFH或者0FFFFH! 請問輸出為0 為什麼是後面兩個。
--?
2
MOV AL, NOT 0FFH
MOV BL,8CH AND 73H
MOV AH ,8CH OR 73H
MOV CH ,8CH XOR 73H
匯編時 計算表達式形成指令為
MOV AL,0----NOT 0FFH=0
MOV BL,0----8CH AND 73H=0
MOV AH ,0FFH--8CH OR 73H=0FFH
MOV CH ,0FFH--8CH XOR 73H=0FFH
請解釋一下第二個程序的每個句子的意思 或結果是怎麼來的
8CH AND 73H=0
8CH =1000 1100B AND 0111 0011B,對位相乘,可得0000 0000B
其它的,演算法雷同。
3
邏輯運算符與8086指令系統中的指令助記符AND 0R 符號完全相同,但是二者是不會混淆的。
作為MASM的運算符是在匯編過程中進行計算的,而指令助記符是在程序執行時進行計算的。
請問匯編過程和程序執行的區別!
--匯編過程,現在都是利用軟體進行。
--早期,是人工查表、計算,把一條條指令的助記符,變成一句句的機器碼。
--程序執行,是由 CPU 執行機器碼。
4請問 指令、機器碼、匯編語言的 異同!
--指令,可以寫成機器碼,也可以寫成助記符,是用來控制 CPU 進行各種操作的。
--匯編語言,是指令、偽指令,各種規則、語法的統稱。
Ⅱ 混淆字元串後能破解嗎
基礎知識
物極必反。我們已經研究了閱讀Windows內核的方法,現在開始討論在 我們自己的驅動編碼中採用特殊的編碼方法,來簡單地防止反匯編閱讀。這是有趣的一種事態:一方面我們研究如何閱讀別人的(尤其是MS的)代碼;另一方面, 我們不得不採取措施保護自己的技術不被他人簡單地竊取。
我這里要用到的這種方法不同於加殼或者加密。加殼和加密的方法比較單一,從而容易被人以同樣單一的方法整體解密,同時內核驅動中進行加密稍顯復雜,難以做 得穩定,而且我手頭沒有成熟的整體加密的代碼。實際上代碼如果在運行,則一定必須被解密,因此從內存中得到解密的代碼並不困難。所以我並不太傾向於使用加 殼或者加密的方案。
劉濤濤的「扭曲變換」是根本的防止逆向解決方案,但是需要付出巨大的努力才得以實現。
下面的一些方法是比較簡單的。這樣的做法顯然不能完全防止逆向,但是能起到一定的「遮掩」作用。好處是隨時可以做,而且可以個人根據代碼的重要程度,決定哪些部位做,哪些部位不做。無論有多簡陋,有勝於無。
劉濤濤的扭曲變換
由於破解技術的發展,實際上大部分商業軟體的合法性驗證機制都變成了僅具有裝飾性,而且一些難以開發的底層軟體的技術細節,往往在發行不久就被人理解並發表在網上。這成為許多開發者厭惡的事(當然另一些開發者則樂於此道)。
於是如何讓編譯後的機器代碼更難以理解就成為一個切實有用的研究方向。編譯器有效地優化了代碼,但這僅僅是將代碼變得更簡單。一般地說,簡單的東西總是比復雜的要容易理解,雖然和源代碼的關系變得模糊了。
國內著名技術牛人劉濤濤在網上發表「扭曲變換」的思想。這個思想和「優化」完全相反,主旨不是讓代碼更簡單、效率更高,而是讓代碼更加復雜——毫無疑問效率也更低。但是相比技術秘密的泄露,效率的損失其實並不那麼重要了。
這種復雜性有著無限的潛力。比如,讀者計劃一次從北京到上海的旅行,最近的直線航行路線當然只有一條。但是如果想要路線更長更復雜的話,則完全有無限種可 能:你可以先從北京抵達紐約,在紐約休息後前往南極,然後北上到達撒哈拉沙漠,最後再前往上海。復雜的代碼使破解者無法找到驗證相關代碼的所在,也使試圖 竊取技術的讀者一無所獲。
劉濤濤的工具可以將編譯後的obj文件進行扭曲,鏈接後生成的可執行文件變得極難閱讀,而且可以反復地執行下去:一段代碼可以無限地變大變長——功能卻是和原來等價的。這真是不可思議的技術。
技術細節
在代碼中,出現了直接字元串是非常不妥的一件事。往往這些常數字元串在反匯編的時候會直接被人看見,對反工程者是最好的引導。
以下的代碼都會暴露我們的字元串:
char *str = "mystr";
wchar_t buffer[2] = { L"hello,world."};
UNICODE_STRING my_str;
RtlInitUnicodeString(&my_str,L"hello,world");
隱藏這些常數字元串並不能完全防止逆向工程,但是毫無疑問的是,會給逆向工程增加很多麻煩。
隱藏這些字元串的手法是:在寫代碼的時候並不寫字元串的明文,而是書寫密文,總是在使用之前解密。這樣的手法的後果是,在靜態反匯編的時候,反工程者是看不見字元串的。但是,反匯編者顯然會在調試的時候看見字元串。
在調試的時候才看見合法的字元串比靜態反匯編的時候看見字元串要麻煩許多,因為一般只有對一段代碼有興趣才去調試它。而之所以對那段代碼有興趣,有些時候是因為看見了感興趣的字元串。全部跟蹤調試所有的代碼,是艱巨的任務,只有具有重大價值的目標才值得那樣去做。
想保護代碼,請首先保密常數字元串。
不過有點要注意的是,你不能把所有的字元串都用同樣的一招進行加密,至少不能用相同的密鑰;否則,也許一個簡單的解密程序就把你所有的字元串恢復為明文了。
考慮:
char *str = "mystr";
改為:
char str[] = { 'm' ^ 0x12, 'y' ^ 0x12, 's' ^ 0x12 ,'t' ^ 0x12,'r' ^ 0x12,'/0' ^ 0x12}
如果認為異或是最簡單的加密方法,那麼0x12就是這里的密鑰。現在編譯出來的字元串已經面目全非了,當然,要解密這個字元串需要一個函數。
char *dazeEstr(char *str, char key)
{
char *p = str;
while( ((*p) ^= key) != '/0')
{ p++; }
return str;
}
你可以試試靜態反匯編下面的代碼:
char *str = { 'm' ^ 0x12, 'y' ^ 0x12, 's' ^ 0x12 ,'t' ^ 0x12,'r' ^ 0x12,'/0' ^ 0x12};
dazeEstr(str,0x12);
printf(str);
當然你通過分析一定會知道printf的結果。調試也可以知道結論,但是比直接用眼睛可以看見可是麻煩多了。當然這樣寫代碼也有些讓人抓狂,但是,你總是可以先按自己的本來的習慣寫完代碼,然後把關鍵的字元串這樣處理。
下面是一個寬字元的處理方法。
wchar_t *dazeEstrW(wchar_t *str, wchar_t key)
{
wchar_t *p = str;
while( ((*p) ^= key) != '/0')
{ p++; }
return str;
}
下面的代碼:
UNICODE_STRING my_str;
RtlInitUnicodeString(&my_str,L"hello,world");
其實總是可以改為:
wchar_t buffer[] = { L"hello,world."};
UNICODE_STRING my_str;
RtlInitUnicodeString(&my_str,buffer);
那麼加密的寫法是:
wchar_t buffer[] = {
L'h' ^ 0x3a,L'e' ^ 0x3a,L'l' ^ 0x3a,L'l' ^ 0x3a,
L'o' ^ 0x3a,L' ^ 0x3a,'L'w' ^ 0x3a,L'o' ^ 0x3a,
L'r' ^ 0x3a,L'l' ^ 0x3a,L'd' ^ 0x3a,L'.' ^ 0x3a,
L'/0' ^ 0x3a};
UNICODE_STRING my_str;
RtlInitUnicodeString(&my_str,dazeEstrW(buffer,0x3a));
比 較明顯的缺陷是書寫常數字元串的時候變得麻煩。我一直在追尋更簡單的寫法,但是遺憾的是,我還沒有找到。怎麼說呢?如果你覺得隱蔽是值得的,那就這樣做。 你甚至可以用更復雜的加密演算法,只要你能算出密文,然後填寫在代碼常數中,不過那樣修改代碼變得太困難了。如果你能寫一個預編譯工具自動修改代碼,確實是 一個好辦法,不過對於一種僅僅防止肉眼直觀看到字元串的方式,更復雜的加密方法往往沒必要,因為無論多復雜的演算法,解密演算法都很容易在你自己的代碼里找到
Ⅲ 匯編語言 and 和 anl 有什麼區別
AND ,ANL,都是邏輯運算的「與」運算指令,區別是:
AND 用於80x86匯編語言,ANL用於是51系列單片機匯編語言。
.
80x86匯編語言「與」運算指令舉例:
若AL初值為 00011111b ,
執行 AND AL,10010001 結果,AL=00010001b
.
51系列單片機匯編語言「與」運算指令舉例:
若P1口存鎖器初值為 11111111b, 累加器A內容為00001111b,
執行 ANL P1,A 結果,P1口存鎖器內容為00001111b
.
AND、ANL指令,多用於屏蔽目的操作數的某些位。
Ⅳ 是不是每個硬體都對應一個不同的匯編語言
你把這兩個概念搞混淆了。匯編語言是一種比機器語言高級的底層語言,他是面向機器的,通常是為特定的計算機或系列計算機專門設計的。因此,不同的處理器有不同的匯編語言語法和編譯器,編譯的程序無法在不同的處理器上執行,缺乏可移植性。並不是說每個硬體對應著不用的匯編。而是不同的處理器架構對應不同的匯編指令集。不過換湯不換葯,只要你掌握了最基礎的,別的也是大同小異的。
希望能幫到你~~
Ⅳ 匯編語言中#20H和#20有什麼區別或者說什麼時候用#20H,什麼時候用#20我有點混淆了。
H是16進制標識
Ⅵ 誰可以發我一個C語言代碼混淆工具,如opqcp
可以考慮在sdk程序編譯時生成匯編中間結果,然後讓人看匯編程序,注意編譯時去掉debug選項
Ⅶ Android 反匯編出來的從a 到z 是什麼,到底是在包名下的才是主要研究的代碼,wps里的類是用來混淆的嗎
這個是混淆過的
Ⅷ 匯編指令and or
一般匯編語言,嵌入式系統中都是使用16進製表示,即XXXXH這樣的表示方式,我們在進行與和或的過程中,首先將16進制數轉化為2進制數,即每一位16進制數分解為4位2進制數,不夠四位補足四位,例:
MOV AX,3044H
OR AL,08H
AL=44H=01000100B
08H=00001000B =01001100B=4CH
所以最後的結果為:AL=4CH
Ⅸ 什麼軟體能將C語言的執行文件反匯編為匯編源代碼
可以使用Linux下的objmp命令來反匯編。
常用命令:
objmp -x obj:以某種分類信息的形式把目標文件的數據組成輸出;<可查到該文件的的所有動態庫>
objmp -t obj:輸出目標文件的符號表
objmp -h obj:輸出目標文件的所有段概括
objmp -j ./text/.data -S obj:輸出指定段的信息(反匯編源代碼)
objmp -S obj:輸出目標文件的符號表,當gcc -g時列印更明顯
objmp -j .text -Sl stack1 | more
-S 盡可能反匯編出源代碼,尤其當編譯的時候指定了-g這種調試參數時,效果比較明顯。隱含了-d參數。
-l 用文件名和行號標注相應的目標代碼,僅僅和-d、-D或者-r一起使用
使用-ld和使用-d的區別不是很大,在源碼級調試的時候有用,要求編譯時使用了-g之類的調試編譯選項。
-j name 僅僅顯示指定section的信息
Ⅹ 為什麼這么多商業Android開發者不混淆代碼
代碼混淆技術基本原理是使反編譯工具反編譯出來的代碼人難以閱讀,從而達到防止被逆向破解的目的。PC上的代碼混淆技術已經很成熟,有加花指令、多態變形等技術手法,Android代碼混淆技術才剛剛起步,目前已知的技術手法如下。
Java類名、方法名混淆
Dalvik位元組碼包含了大量的調試信息,如類名、方法名、欄位名、參數名、變數名等,使用反編譯工具可以還原這些信息。由於類名、方法名等通常都會遵循一定的命名規范,破解者很容易根據這些信息來猜測代碼功能,閱讀起來就跟查看源代碼一樣。從Android 2.3開始,Google在SDK中加入了一款叫ProGuard的代碼混淆工具,ProGuard會刪除這些調試信息,並用無意義的字元序列來替換類名、方法名等,使得使用反編譯出來的代碼難以閱讀,提升逆向難度。使用ProGuard混淆過過後,反編譯出來的類名和方法名無法閱讀,但是反編譯出來的功能代碼仍然是非常容易閱讀的,和源代碼差不多,破解者仍通過閱讀功能代碼來自行標記類名、方法名等,然後逆向破解。[2]
Java代碼混淆
通過對功能代碼流程進行亂序混淆,實際運行時亂序混淆後的代碼流程卻和原始代碼流程是一樣的,但反編譯出來的代碼流程靜態閱讀時與原始流程有很大差異,使破解者很難通過靜態分析理解代碼功能,從而保護代碼不被逆向分析。比如,原始的代碼流程是1->2->3->4->5->6->7,經過亂序混淆後靜態反匯編查看到的代碼流程可能變成2->7->5->1->6->4->3,實際運行時代碼流程仍然是1->2->3->4->5->6->7。目前使用這種代碼混淆技術的Android保護工具有APKProtect。[1]