CAndPrimer_05

本文探讨了C语言中的位操作与指针应用,包括条件运算符的使用、位数组定义与操作、以及如何通过位操作实现整数位字段的插入。提供了详细的代码示例与解析。

C和指针 第五章 操作符和操作表达式

1,操作符的应用

  • ?操作符使用
if (a >5) 
    b[2 *c + d( e /5 )] =3;
else
    b[2 *c + d( e /5 )] =20;
//相当于下面表达式
b[2 *c + d( e /5 )] = a >5 ? 3 : 20;  

2, 记录位操作符问题

  • 位数组定义
    位数组问题:存放于一个char 的字符数组中 对应的位的0 和 1即代表着数字
    我们知道一个char 类型字符为 1 byte = 8 bit 相当于对应着8个位置
    例如 a[0] ->0 ~7 ; a[1] ->8 ~15; a[2] ->16 ~23 …… 当你需要表示数字7 则使a[0] = 0000 0001 (相应的第七位置 1 即可)
    这样 我们可以用字节的位 来表示数 可以更好的利用内存进行存储

  • 代码实现部分

 
void set_bit( char bit_array[], unsigned bit_number ) {         
    bit_array[bit_number >>SHIFT] |= ( 1 << ((bit_number & MASK)) );  
}
void set_bit_v1( char bit_array[], unsigned bit_number ) {       
    bit_array[bit_number >>SHIFT] |= ( 1 << (7 -(bit_number & MASK)) );
    
}
void clear_bit( char bit_array[], unsigned bit_number ) {
    bit_array[bit_number >>SHIFT] &= ~( 1 <<(bit_number & MASK) );
}
void assign_bit( char bit_array[], unsigned bit_number, int value ) {
    if(value) set_bit(bit_array, bit_number);
    else  clear_bit(bit_array, bit_number);
}
int test_bit( char bit_array[], unsigned bit_number ) {
    return bit_array[bit_number >>SHIFT] & ( 1 << (bit_number & MASK) );
}
char* init_bitarray(int size) {
    char* temp;
    temp =malloc(size /8 +1); //+1 意味着处理 NUL 字符
    memset(temp, 0, (size /8 +1)); //initialize to 0
    return temp;
}

  • 对应的代码部分的解释

    例如 原来25-> 0000 0010 现在 25-> 0100 0000
    所以7 -(bit_number & MAS) 就是直接将顺序正过来了
    (bit_number & MAS) 代表1 所左移几位
    所以8 -(bit_number & MAS) 就是直接将顺序正过来了
    (bit_number & MAS) 代表1 所左移几位

  • 逻辑上的一次错误

    错误在循环的时候出现过,导致对于7,13,,23 这一类不能准确的输出打印对应的是例如 a 字符数组进行储存位数组
    7-> a[0] 0000 0001 13-> a[1] 0000 0001 23-> a[2] 0000 0001

    循环要有8次 才能准确输出
    下面代码展示记录错误 //0x80 =128 =1000 0000 此处应该循环8 次 记录填坑 j 从0 到8结束 才能准确的遍历

for (int i = 0; i < 4096 / 8 + 1; i++)
	{
		for (int j = 0; (j < 8 && k < 10); j++)
		{
			if ((bit_arr[i] & 0x80) == 0x80) 
			{
				num[k] = i * 8 + j +1;
				k++;
			}
			bit_arr[i] <<= 1;
		}
	}

3,位操作符应用

题目描述:
把一个整数插入到一个整数所规定的位置里面 起始位是一定大于结束位的
可以更清楚的表明下面的返回值:

原始值需要存储的值起始位结束位返回值
0x00x1440x10
0xffff0x1231540x123f
0xffff0x1231390xc7ff
  • 过程思路 以最后一个为例
    1. 创建一个掩码 mask 把需要存储的那几个为设置为1,此时的掩码为0011 1110 0000 0000
    2. 用掩码的 反码对原值进行 & 操作 讲那几个设置的位置为0. 原值为 1111 1111 1111 1111 操作后变为1100 0001 1111 1111
    3. 将新值左移,使它与那几个需要存储的位进行对齐。新值 0X0123 0000 0001 0010 0011 ,左移后变为 0100 0110 0000 0000.
    4. 把移位后的值与原码进行 & 操作 ,只保留需要设定的那几个位的值。造作之后,结果为0000 0110 0000 0000.
    5. 把结果与原值 进行 | 操作 。结果变为 1100 0111 1111 1111 0Xc7ff
      Finish!!!

代码如下:

int store_bit_field(int orginal_value, int value_to_store, unsigned starting_bit, unsigned ending_bit) {
    unsigned mask =0x0000, temp;
    int i, j;
    for(i =0; i <=(starting_bit -ending_bit); i++) {
        mask |= (1 << (ending_bit +i));
    }
    orginal_value =( orginal_value & (~ mask) ); //原值 与mask 反码 & 操作
    value_to_store <<=ending_bit;
    value_to_store &= mask;
    value_to_store |= orginal_value;
    print_bin(value_to_store);
    printf("\n0x%x\n", value_to_store );
}

对于第一部 mask 的取值 思路:
利用一个 0000 0000 0000 0000 与对应的位(用 0000 0000 0000 0001 进行移位)进行 | (或) 操作 可取的 mask 值

表格学习工具

左对齐右对齐居中对齐
单元格单元格单元格
单元格单元格单元格
内容概要:本文详细记录了对一个Android ARM64静态ELF文件中字符串加密机制的逆向分析过程。该ELF文件的所有字符串均被加密,无法通过常规strings命令或IDA直接识别。作者通过分析发现,加密字符串存储在.rodata段,其解密所需信息(包括密文地址、长度和16位密钥)保存在.data.rel.ro段的40字节描述符中。核心解密函数sub_10F408采用自反的双pass流密码算法,结合固定密钥KEY_TERM(由.data段24字节数据计算得出),实现字节级非线性、位置与长度相关的加密。文章还复现了完整的Python解密脚本,并揭示了该保护机制的本质为代码混淆而非强加密,最终成功批量解密全部956条字符串,暴露程序真实行为,如shell命令模板、设备标识篡改、网络重置等操作。此外,文中还提及未启用的自定义壳框架及其反dump设计。; 适合人群:具备逆向工程基础的安全研究人员、二进制分析人员及对ELF保护技术感兴趣的开发者。; 使用场景及目标:①学习ELF二进制中字符串加密的典型实现方式与逆向突破口;②掌握从结构识别、函数追踪到算法还原的完整逆向流程;③理解“绑定二进制”的完整性校验设计及其局限性;④实践编写IDAPython脚本自动化提取与解密敏感数据。; 阅读建议:此资源以实战案例驱动,不仅展示技术细节,更强调逆向思维与验证方法,建议读者结合IDA调试环境,逐步跟随文中步骤进行动态分析与算法验证,深入理解每一步的推理依据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值