-
-
[原创]CTF第二题的求解思路
-
2017-10-27 20:23 2409
-
工具IDA,OD,VC++
不知道如果最后扫描不出来结果可不可以通过
求解主要是获取到两个变量v1和v2,同时满足以下等式
v1 mod 5 = -1890567614 mod 5
v1 mod 17 = -207009661 mod 17
v0 mod 13 = -279954878 mod 13
v0 mod 7 = 866732163 mod 7
根据剩余定理可以推测出v1和v0的可能的一系列值,然后再暴力尝试可能的值,最后确定出v1和v0的值
破解代码如下:
不知道如果最后扫描不出来结果可不可以通过
求解主要是获取到两个变量v1和v2,同时满足以下等式
5 * (v1 - v0) + v1 == -1890567614 && 13 * (v1 - v0) + v0 == -279954878
17 * (v1 - v0) + v1 == -207009661 && 7 * (v1 - v0) + v0 == 866732163
可以看出v1 mod 5 = -1890567614 mod 5
v1 mod 17 = -207009661 mod 17
v0 mod 13 = -279954878 mod 13
v0 mod 7 = 866732163 mod 7
根据剩余定理可以推测出v1和v0的可能的一系列值,然后再暴力尝试可能的值,最后确定出v1和v0的值
破解代码如下:
#include "stdafx.h" #include "stdio.h" //中国剩余定理 struct node { int divisor; //表示除数 int remainder; //表示余数 }T[1000]; //求最大公约数 int gcd(int n, int m) { return m ? gcd(m, n%m) : n; } int v1[0x7ffffff] = { 0 }; int v0[0x7ffffff] = { 0 }; int getV(int b0, int b1, int l0, int l1, int* v) { //MAX_NUM表示的是所求的解的范围的最大值,MIN_NUM表示所求的解的范围的最小值, //n表示的是同于方程的个数,m表示的是三个除数的乘积,gcd_max表示的是两个数的最大公约数,因为三个除数是互素的 //所以gcd_max=1; int i, j, n, t = 0, m = 1, sum = 0, gcd_max = 0, MAX_NUM, MIN_NUM; //printf("请输入有几个方程:\n"); //如上题韩信点兵。输入3 //scanf_s("%d", &n); printf("请输入每组数据( 余数 除数):\n"); // 3 2 5 4 7 6 n = 2; T[0].remainder = b0 % l0; T[0].divisor = l0; T[1].remainder = b1 % l1; T[1].divisor = l1; //printf("请输入所求值的值域:min max\n"); //scanf_s("%x%x", &MIN_NUM, &MAX_NUM); //求出三个除数的乘积m for (i = 0; i < n; i++) { gcd_max = gcd(T[i].divisor, gcd_max); m = m * T[i].divisor; } gcd_max *= m; //求mI for (i = 0; i < n; i++) { t = 0; m = 1; for (j = 0; j < n; j++) { if (j != i) { t = gcd(T[j].divisor, t); m = m * T[j].divisor; } } t = m * t; m = t; while (m % T[i].divisor != 1) m += t; sum += m * T[i].remainder; } printf("最小的值为:\n"); printf("%d\n", sum % gcd_max); printf("在所求的值域内值:\n"); printf("%x\n", sum); int count = 0; while (sum < 0x7e7e7e7e) { if (sum >= 0x20202020) { //&& (sum & 0xff000000) >= 0x20000000 && (sum & 0xff000000) <= 0x7e000000 //&& (sum & 0x00ff0000) >= 0x00200000 && (sum & 0x00ff0000) <= 0x007e0000 //&& (sum & 0x0000ff00) >= 0x00002000 && (sum & 0x0000ff00) <= 0x00007e00 //&& (sum & 0x000000ff) >= 0x00000020 && (sum & 0x000000ff) <= 0x0000007e) { //printf("0x%x \n", sum); v[count] = sum; count += 1; } sum += gcd_max; } printf("%x\n", sum); printf("%d\n", count); return count; } int main() { int b0 = 0x8F503a42; int b1 = 0xEF503a42; int b2 = 0xF3A94883; int b3 = 0x33A94883; printf("%i<->5\n", b0 % 5); printf("%i<->17\n", b2 % 17); printf("%i<->13\n", b1 % 13); printf("%i<->7\n", b3 % 7); int len1 = getV(b0, b2, 5, 17, v1); int len0 = getV(b1, b3, 13, 7, v0); for (int i = 0; i < len1; ++i) { for (int j = 0; j < len0; ++j) { if ((5 * (v1[i] - v0[j]) + v1[i]) == b0 && (13 * (v1[i] - v0[j]) + v0[j]) == b1 && (17 * (v1[i] - v0[j]) + v1[i]) == b2 && (7 * (v1[i] - v0[j]) + v0[j]) == b3) { printf("*********\n"); printf("v1=0x%x\n", v1[i]); printf("v0=0x%x\n", v0[j]); } } } printf("No Solution!\n"); return 0; } #include "stdafx.h" #include "stdio.h" //中国剩余定理 struct node { int divisor; //表示除数 int remainder; //表示余数 }T[1000]; //求最大公约数 int gcd(int n, int m) { return m ? gcd(m, n%m) : n; } int v1[0x7ffffff] = { 0 }; int v0[0x7ffffff] = { 0 }; int getV(int b0, int b1, int l0, int l1, int* v) { //MAX_NUM表示的是所求的解的范围的最大值,MIN_NUM表示所求的解的范围的最小值, //n表示的是同于方程的个数,m表示的是三个除数的乘积,gcd_max表示的是两个数的最大公约数,因为三个除数是互素的 //所以gcd_max=1; int i, j, n, t = 0, m = 1, sum = 0, gcd_max = 0, MAX_NUM, MIN_NUM; //printf("请输入有几个方程:\n"); //如上题韩信点兵。输入3 //scanf_s("%d", &n); printf("请输入每组数据( 余数 除数):\n"); // 3 2 5 4 7 6 n = 2; T[0].remainder = b0 % l0; T[0].divisor = l0; T[1].remainder = b1 % l1; T[1].divisor = l1; //printf("请输入所求值的值域:min max\n"); //scanf_s("%x%x", &MIN_NUM, &MAX_NUM); //求出三个除数的乘积m for (i = 0; i < n; i++) { gcd_max = gcd(T[i].divisor, gcd_max); m = m * T[i].divisor; } gcd_max *= m; //求mI for (i = 0; i < n; i++) { t = 0; m = 1; for (j = 0; j < n; j++) { if (j != i) { t = gcd(T[j].divisor, t); m = m * T[j].divisor; } } t = m * t; m = t; while (m % T[i].divisor != 1) m += t; sum += m * T[i].remainder; } printf("最小的值为:\n"); printf("%d\n", sum % gcd_max); printf("在所求的值域内值:\n"); printf("%x\n", sum); int count = 0; while (sum < 0x7e7e7e7e) { if (sum >= 0x20202020) { //&& (sum & 0xff000000) >= 0x20000000 && (sum & 0xff000000) <= 0x7e000000 //&& (sum & 0x00ff0000) >= 0x00200000 && (sum & 0x00ff0000) <= 0x007e0000 //&& (sum & 0x0000ff00) >= 0x00002000 && (sum & 0x0000ff00) <= 0x00007e00 //&& (sum & 0x000000ff) >= 0x00000020 && (sum & 0x000000ff) <= 0x0000007e) { //printf("0x%x \n", sum); v[count] = sum; count += 1; } sum += gcd_max; } printf("%x\n", sum); printf("%d\n", count); return count; } int main() { int b0 = 0x8F503a42; int b1 = 0xEF503a42; int b2 = 0xF3A94883; int b3 = 0x33A94883; printf("%i<->5\n", b0 % 5); printf("%i<->17\n", b2 % 17); printf("%i<->13\n", b1 % 13); printf("%i<->7\n", b3 % 7); int len1 = getV(b0, b2, 5, 17, v1); int len0 = getV(b1, b3, 13, 7, v0); for (int i = 0; i < len1; ++i) { for (int j = 0; j < len0; ++j) { if ((5 * (v1[i] - v0[j]) + v1[i]) == b0 && (13 * (v1[i] - v0[j]) + v0[j]) == b1 && (17 * (v1[i] - v0[j]) + v1[i]) == b2 && (7 * (v1[i] - v0[j]) + v0[j]) == b3) { printf("*********\n"); printf("v1=0x%x\n", v1[i]); printf("v0=0x%x\n", v0[j]); } } } printf("No Solution!\n"); return 0; }
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
赞赏
他的文章
看原图