zoukankan      html  css  js  c++  java
  • XOR 加密

    XOR 是一个神奇的运算符, 观察它的真值表, 很容易得到以下结论:

    假设现有 a , b 变量, 则

    a ^ 0 == a

    a ^ 0xff == ~a (取反加1等于作为补码的a的真值的相反数的补码, 比如0xff 取反加1 为 -1 的相反数 1 的补码 0x1, 0x0 取反加1 等于 0 的相反数 0 的补码, XOR 和相反数挂钩了!)

    a ^ a == 0

    XOR 满足交换律和结合律

    a ^ b == b ^ a

    a ^ b ^ a == b ^ (a ^ a) == b ^ 0 == b

    这样一来, 可以使用一个中间变量 b , 使得 a ^ b 的值可以复原为 a , 这不正符合动态加密的需求吗?

    说这些很无聊, 观察以下程序:

    请问输出是什么? 抱歉, 我选择死亡!

    问尼玛啊, 直接 Run 后观察不就好了?

    如果你的程序有这种类似的提示, 那么很抱歉, 你将带给黑客极其重要的线索, 他只需简单地一调试, 关键代码就被定位到啦!

     比如使用x64dbg定位字符串

    剩下的先不说了, 我们写一个加密的程序吧?

    这样一来, 可以在代码中使用混淆的数据了, 注意把解密函数和密钥隐藏起来哦.

    /**
    	*加密神器
    	*对 long 和字符串进行 XOR 加密
    	*/
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <locale.h>
    #include <tchar.h>
    #include <string.h>
    
    unsigned int key;
    
    // 打印Usage
    void printUsage();
    
    // initializing
    void init();
    
    // encry
    int encry(void *source, unsigned char key, unsigned short length);
    
    // get the hex type string
    char *catX(const char *source, unsigned short length);
    
    // decode
    char *decode(const char *source, unsigned char key);
    void *ndecode(const void *source, unsigned char key, unsigned short length);
    
    ///////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////
    int
    main(int argc, const char **argv) {
    	init();
    	if (argc != 4) {
    $Return:
    		printUsage();
    		return 0;
    	}
    	
    	if (sscanf(argv[3], "%x", &key) != 1) {
    		wprintf(L"key是一个 8 bit 十六进制数, 请检查!
    ");
    		return 1;
    	}
    	
    	if (strcmp(argv[1], "-s") == 0) {
    		// eg: encry -s "支付失败!" 33
    		// 用户选择的是字符串加密
    		int length = strlen(argv[2]);
    		
    		wprintf(L"加密字符串 "%S" , 共 %d 个字节.
    ", argv[2], length);
    		
    		char *str = (char *) malloc(length + 1);
    		if (str == NULL)
    			return 2;
    		if (strncpy(str, argv[2], length+1) == NULL){
    			return 1;
    		}
    		
    		if (encry(str, key, length) != 0)
    			return 1;
    			
    		wprintf(L"加密后显示为(key-0x%X):
    "
    						 L""%S"", key, (const char *)str);
    		puts("");
    		
    		wprintf(L"加密前后的 ASCII 字串形式:
    "
    						 ""%S"
    "
    						 ""%S"
    ", catX(argv[2], length), catX(str, length));
    		
    		char *deco = decode(str, key);
    		wprintf(L"尝试解码:
    "
    						 ""%S"", deco);
    		
    		free(str);
    		free(deco);
    		
    	} else if (strcmp(argv[1], "-n") == 0) {
    		// 用户选择的是 long 加密
    		long n = 0;
    		if (sscanf(argv[2], "%ld", &n) != 1) {
    			wprintf(L"请检查输入!
    ");
    			return 1;
    		}
    		
    		wprintf(L"加密整数 %ld :
    ", n);
    		encry(&n, key, sizeof(n));
    		printf("0x%lX
    ", n);
    		wprintf(L"尝试解密:
    %ld
    ", *(long *)ndecode(&n, key, sizeof(n)));
    		
    	} else {
    		goto $Return;
    	}
    	
    	return 0;
    }
    
    void 
    init() {
    	// 本地化相关
    	setlocale(LC_CTYPE, "");
    }
    
    void 
    printUsage() {
    	printf("%S", L"Usage:
    "
    					"	 encry -s <要加密的字符串> <key>
    "
    					"	 encry -n <要加密的整数> <key>
    ");
    }
    
    int
    encry(void *source, unsigned char key, unsigned short length) {
    	if (source == NULL) {
    		printf("NULL Pointer Exception
    ");
    		return -1;
    	}
    	int i = 0;
    	for (; i < length; i ++ ) {
    		((unsigned char *) source)[i] ^= key;
    	}
    	
    	return 0;
    }
    
    char *
    catX(const char *source, unsigned short length) {
    	if (source == NULL) {
    		return NULL;
    	}
    	int n = 4 * length, i = 0;
    	char *str = (char *) malloc(n + 1);
    	*str = '';
    	
    	for (; i < length; i ++ ) {
    		unsigned char byte = source[i];
    		char tmp[5] = { 0 };
    		tmp[0] = '\';
    		tmp[1] = 'x';
    		sprintf(&tmp[2], "%x", byte);
    		strcat(str, tmp);
    	}
    	
    	return str;
    }
    
    char *
    decode(const char *source, unsigned char key) {
    	if (source == NULL) {
    		printf("NULL Pointer Exception
    ");
    		return NULL;
    	}
    	
    	int length = strlen(source);
    	char *str = (char *) malloc(length + 1);
    	strncpy(str, source, length + 1);
    	
    	while (*str != '') {
    		*str++ ^= key;
    	}
    	
    	return str - length;
    }
    
    void *
    ndecode(const void *source, unsigned char key, unsigned short length) {
    	if (source == NULL)
    		return NULL;
    	void *data = malloc(length);
    	
    	memcpy(data, source, length);
    	
    	int i = 0;
    	
    	for (; i < length; i ++ ) {
    		((char *) data)[i] ^= key;
    	}
    	
    	return data;
    }
    ///////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////
    

      

  • 相关阅读:
    《从0开始学架构》——学习笔记(基础篇和高性能篇)
    Oracle的数据并发与一致性详解(下)
    Oracle的数据并发与一致性详解(上)
    关于oracle的缓冲区机制与HDFS中的edit logs的某些关联性的思考
    分布式锁的两种实现方式(基于redis和基于zookeeper)
    hadoop配置文件详解系列(二)-hdfs-site.xml篇
    hadoop配置文件详解系列(一)-core-site.xml篇
    【管理心得之四十六】你呀,少肺
    【管理心得之四十五】你呀,没心
    【管理心得之四十四】独立冲突之外,你做不到
  • 原文地址:https://www.cnblogs.com/develon/p/9762898.html
Copyright © 2011-2022 走看看