0%

14-移位

移位与内存分配

移位

  1. 算术移位
  2. 逻辑移位
  3. 循环移位

算术移位

逻辑移位

循环移位

带进位的循环移位指令

练习

  1. 定义一个unsiged char 类型,通过程序为第3、5、7位赋值,赋值时不能影响到其它位原来的值.(使用位操作指令、比如:& | ! ^ << >>等)
  2. 判断某个位的值是否为1. (使用位操作指令、比如:& | ! ^ << >>等)
  3. 取第7、6、5位的值,以十进制显示(unsigned).(使用位操作指令、比如:& | ! ^ << >>等)
  4. 用十六进制文本编辑器分别打开一个.exe、.dll、.sys、.txt、.doc .jpg、.pdf等将前四个字节写在下了.
  5. 将一个在十六进制编辑器中打开的.exe文件,拖拽到最后,观察文件中的大小和硬盘上的大小.

习题1解答

1
2
3
4
5
6
7
8
9
10
void test()
{
unsigned char num = 0x95;//10010101
//num = num & 1111 1011; 3
int result = num & 0xfb;//0x91
//num = num & 1110 1111;
result = num & 0xef;//0x85
//num = num ^ 0x40; 7
result = num ^ 0x40;//
}

后来我想了下,这种方法根本不通用,就想了别的办法

1
2
3
4
5
6
7
8
9
10
11
12
int test(int num, int i, int set)
{
int result1 = num >> (i-1);
if(set == 1)
result1 = result1 | 1;
else
result1 = result1 >> 1 << 1;
result1 = result1 << (i-1);
int move = 9-i;
int result = result1 + ( ((num << move)&0xff) >> move);
return result;
}

这个i是第n位,而set是要设置的值,这个是通用的,8位数据可以用这个

习题2解答

1
2
3
4
int test1(int num, int i)
{
return num >> (i-1) & 0x1
}

习题3解答

1
2
3
4
5
int test2(int num, int i)
{
int result = (num >> (i-3)) & 0x7;
return result;
}

习题4解答

类型字节
exe4d5a5000
txtCEE1B0AE
dll4D5A9000
png89504E47
pdf25504446
doc504B0304

发觉exe跟dll相对比较吻合,而其余都是不同的

习题5解答

发觉文件中的大小,跟硬盘上的大小只差那个几个字节,只有4个字节左右的差异

内存分配与文件读写

练习

  1. 用十六进制文本编辑器,打开一个记事本的.exe文件,再打开在内存中的记事本进程,记录下这两个文件的不同.
  2. 将记事本的.exe文件读取到内存,并返回读取后在内存中的地址.
  3. 将内存中的数据存储到一个文件中,(.exe格式),然后双击打开,看是否能够使用.

习题1解答

  1. 发觉这两个相同的部分只有文件开头部分,后面的都是很多不同的了
  2. 地址全部是不同的,一个以0为基础,一个以0x400000为基础

习题2+3解答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

char* getAddr(long *size, char *path)
{
FILE *fp;
if((fp=fopen(path,"rb+"))==NULL)
{
printf("error\n");
return NULL;
}
if(fseek(fp,0, SEEK_END) !=0)
{
printf("fseek error\n");
return NULL;
}
*size = ftell(fp);
if(*size == -1)
{
printf("size error\n");
return NULL;
}
if(fseek(fp,0, SEEK_SET) != 0)
{
printf("fseek error\n");
return NULL;
}
char* file_buffer = (char*)malloc(*size+1);
if(file_buffer == NULL)
{
printf("malloc error\n");
return NULL;
}
if(fread(file_buffer, *size, 1, fp) == 0)
{
printf("read error\n");
return NULL;
}
file_buffer[*size] = '\0';
fclose(fp);
return file_buffer;
}

void writeFile(char *path, char *addr, long size)
{
FILE *fp;
if((fp=fopen(path,"wb+"))==NULL)
{
printf("error\n");
return ;
}
if(fwrite(addr, size, 1, fp) == 0)
{
printf("write error\n");
return ;
}
}
int main(int argc, char* argv[])
{
long size = 0;
char *addr = getAddr(&size, "MC.EXE");
writeFile("test2.exe", addr, size);
return 0;
}

其实也不难,就是简单的读写,注意,rb+ 和wb+才能成功,要以二进制流的形式读写,练习3的答案,能打开,因为写了后也是一样的文件

本文作者:NoOne
本文地址https://noonegroup.xyz/posts/1f1233d7/
版权声明:转载请注明出处!