首页 > 其他分享 >逆向——字符与字符串,中文字符GB2312编码由来

逆向——字符与字符串,中文字符GB2312编码由来

时间:2023-04-02 21:11:38浏览次数:32  
标签:字符 存储 逆向 打印 GB2312 编码 printf

字符与字符串

在之前的课程中我们了解到变量的定义决定两个事情,第一是决定存储的数据宽度,第二是决定了存储的数据格式,那么我们来看下下面的代码:

int a = 123; // 变量x,数据宽度为4个字节,里面存储的是补码(在计算机系统中,数值一律用补码来存储) int float b = 123.4F; // IEEE编码(浮点) int c = 'A'; // 那这个存储的是啥?

 

我们在代码中写了变量c,但是它最终存储进去的是啥呢?我们看下反汇编:

images/download/attachments/12714021/image2021-2-19_0-51-43.png

在这里'A'存储的时候变成了0x41,这是为什么?因为它是一个字符,这里需要注意在变量定义赋值时,赋值字符需要加上单引号。

在内存中所有东西最终都会变成0和1,A对应0x41,那么可以大胆猜测一下B就是对应0x42,当我们使用字符存储到内存时,字符自然是没办法存储到内存中的,这时候就有了一个字符对应的表:ASCII表(美国标准信息交换代码)

images/download/attachments/12714021/image2021-2-19_0-56-21.png

这张表有128个符号,都是比较常用的,那也就是说在我们赋值A给变量时,编译器会去这张表中寻找大写的A,如上图所示A对应10进制为65,转为16进制就是0x41。

值得注意的是在这张表中最多也就是占用一个字节的宽度,所以我们完全没有必要使用int来存储字符,可以选择char,例如:char a = 'A';

在很多书中会描述char就是用来存储字符的,这是一个错误的说法,数据的存储是由使用者决定的而不是计算机。

C语言会自带很多函数提供我们使用,我们想要在控制台中输出一个字符,可以使用putchar这个函数:

putchar(65); putchar('A');

如上代码就是输出一个字符A,这样我们就了解了这个函数的运行本质:将对应数从ASCII表中查出画在(打印)控制台上;需要注意该函数一次只能打印一个字符。

除了这个函数外还有一个打印输出的函数:printf,它就可以一次性打印多个字符。

#include <stdio.h>   void main() { printf("Hello World!\n");   int x = 0xFFFFFFFF; printf("%d %u %x\n",x,x,x); // -1 4294967295 ffffffff   float f = 3.1415F; printf("%6.2f\n",f); // 3.14 }

使用printf函数需要在代码开头写#include <stdio.h>,三个printf分别表示输出字符串、整数、浮点数。

有心之人可能会发现在使用printf函数时,有好几个百分号的东西,这就叫做占位符,一共分为如下这几种:

%d 有符号数形式打印

%u 无符号形式打印

%x 16进制形式打印

%{x.y}f 打印浮点数 x标志打印总长度 y 代表小数点后长度

看过示例代码之后,我们就知道了字符串本质上就是一堆字符连续串在一块,观察一下反汇编代码:

images/download/attachments/12714021/image2021-2-19_1-19-37.png

这时候就存在一个问题,printf为什么会知道打印完最后一个感叹号之后就不打印了呢?这是因为在这一串字符串后存在着一个00,当printf看见之后就会停止打印了,也就是说字符串的结束标志在内存中是00。

我们想使用char类型来存储字符串,就需要用到数组,例如:

char buffer[20] = "Hello World!"; printf("%s\n",buffer);

这就表示buffer可以存储20个字符,%s是占位符,表示以字符串形式打印,关于数组的细节后面的课程中会学习到,这里了解一下即可。

中文字符

在之前了解到ASCII码表中,我们并没有发现存在中文,那么如何在计算机中存储中文?这时候我们需要了解一个新的表:拓展ASCII码表 (EASCII)

images/download/attachments/12714021/image2021-2-19_1-27-21.png

该表十进制值从128到255,但是这些也没办法满足我们中文的需求,所以天朝专家把那些127号后的奇异符号们 (即EASCII)取消掉,规定:一个小于127的字符意义与原来相同,但是两个大于127的字符连在一起时,就表示一个汉字,这样我们就可以组合出大约7000多个简体汉字了。

在这些编码里,连在ASCII里本来就有的数字、标点、字母都统统编了两个字节长的编码,这就是常说的”全角“字符,而原来在127号以下的那些就叫”半角“字符了,上述编码规则就是GB2312或GB2312-80。

GB2312或GB2312-80,两种编码可能使用相同的数字代表两个不同的符号,或者使用相同的数字代表不同的符号,这种编码方式有很大的弊端,当此种编码方式的数据在其他国家使用的时候,如果其他国家使用类似的编码规则,那么数据就会失去原本的意义

而前辈们早就发现了这种情况,因此Unicode编码就是为了解决这个问题才出现的。

在C语言中写入中文与其他字符串没区别,但我们了解过GB2312或GB2312-80编码规则后,就要知道一个中文代表2个字节:

char buffer[20] = "中国"; printf("%s\n",buffer);

images/download/attachments/12714021/image2021-2-19_1-33-38.png



标签:字符,存储,逆向,打印,GB2312,编码,printf
From: https://www.cnblogs.com/bonelee/p/17281367.html

相关文章

  • 逆向——C语言的汇编表示之堆栈图 手把手示例 可以考虑在函数内部加一个局部变量来综
    课程概要来自:https://gh0st.cn/Binary-Learning/C%E8%AF%AD%E8%A8%80.html写得非常详细本章课程需要具备汇编语言基础,若无汇编语言基础是无法去理解课程中所讲的一些知识点和技术细节的;同时也表示本课程是以汇编语言来理解C语言,透过本质理解高级语言。关于本节课的环境:VC6,VC6......
  • 逆向——从一个实际例子看EBP+4为何是函数的返回地址
    第六节1、逆向CRACKME1、OD加载CRACKME后,为啥地址停在0x00401000?--需要知道什么是PE结构。  ——————2、出现这个框,表示程序已经执行完判断。3、弹出窗口是WIN32API的知识,它是API的MessageBoxA函数实现的功能。  ——————4、如何正确的下断点?(1)在OD......
  • 【UNCTF逆向】pytrade详解
    前段时间有点别的东西在忙,最近会加大力度。题目pytrade解法这道题的内容是一些opcode也就是python编译的字节码。网上搜的一些教程是叫手扒,就简单学习了一下。变量constfast(有形参和局部变量之分)global(全局)数据结构listdictionaryslice循环whileforinif函数函数范......
  • C语言逆向分析——IF条件语句的反汇编,要熟悉各种if的姿势以及与或非表达式组合
    第四课IF语句的反汇编判断  第四课练习1intplus(intY,intX){intN=t;if(X<Y)t=t+Y;//t=N+yC}voidmain(){plus(5,4);}第五课IF...ELSE...语句的反汇编判断IF…ELSE…语句的反汇编判断:  ......
  • 逆向——如何区分全局变量和局部变量
    第三节局部变量与全局变量的区别记住知识点:1、全局变量,在程序生成后,内存地址是固定了,只有重新编译后,内存地址才会改变。2、全局变量,在汇编中是内存地址的格式存储;局部变量是以[ebp-xxx]的格式存储。  局部变量与全局变量的区别全局变量与局部变量的区别在于作用域的......
  • WebAssembly逆向
    一、WebAssembly简介WebAssembly是一种可以使用非JavaScript编程语言编写代码,并且能在浏览器上运行的技术方案。借助Emscripten编译工具,能将C/C++文件转成wasm格式,JavaScript可以直接调用该文件并执行其中的方法。好处可以隐藏核心逻辑,增大逆向难度提高执行效率(基于C/......
  • re/【unity】游戏逆向首试 [BJDCTF2020]BJD hamburger competition
    本题是是一个unity游戏,而且是以c#和.net编写尝试直接用idea进行反汇编,但是没有找到运行逻辑,后来在大佬的wp上发现是利用dnspy对c#的dll文件进行返回编,进而获得结果。反汇编BJDhanburgercompetirion_Data中的Assembly-CSharp.dll即可获得如下代码段:可以看到先利用sha1进行加......
  • leetcode 394.字符串解码 Java
    394.字符串解码给定一个经过编码的字符串,返回它解码后的字符串。编码规则为:k[encoded_string],表示其中方括号内部的encoded_string正好重复k次。注意k保证为正整数。你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。此外......
  • 逆向——浮点数的表示,遇到了就去在线查吧,还原起来比较难受
    第二节2.5数据类型与存储 浮点数这玩意自己去在线转换下就行了: http://www.styb.cn/cms/ieee_754.php     详细:         第二节2.6浮点数的存法记住知识点:1、小数点左移,指数部分:指数减1的二进制数  2、小数点右移,指......
  • 循环输出字符串魔板,动态字段
    names=["吴*平(语文)","张学*(语文)","袁莹*(语文)","宋丹*(语文)","...","廉*峰(会计)"]for(nameofnames)console.log(`${name}\n很满意\n满意\n基本满意\n不满意\n\n${name}师德不满意的原因[多选题]\nA歧视......