注意下name和password

image.png
比如这种形式:字符串+有顺序数字
以便于我们分析是查找

分析关键函数算法

image.png

大致查看关键函数

image.png

详细分析关键函数并写出部分密钥算法

image.png

  1. #include <iostream>
  2. #include <Windows.h>
  3. #include <time.h>
  4. int main()
  5. {
  6. srand(time(NULL));
  7. byte K[10] = { 0x11, 0x22, 0x33 ,0x9C, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA };
  8. //第一个call关系:
  9. //al = (k0^k6 ^ 0X18 + 0X3D) ^ 0XA7;
  10. //判断al大于0才是正确密钥
  11. while (true)
  12. {
  13. byte k0 = rand() % 0xFF;
  14. byte k6 = K[6];
  15. byte al = (k0^k6 ^ 0X18 + 0X3D) ^ 0XA7;
  16. if (al>=9)
  17. {
  18. K[0] = k0;
  19. K[6] = k6;
  20. break;
  21. }
  22. }
  23. //第二个call关系:
  24. //ESI = (0X100 * (k1 ^ k7 & 0XFF) + k2 ^ k5 & 0XFF) & 0XFFFF;
  25. //EAX = (((ESI ^ 0x7892) + 0x4d30) ^ 0x3421) & 0xffff;
  26. //如果没有余数,则返回商;有余数,则返回0
  27. //没有余数才是正确的,并且商必须小于等于0x3E8
  28. while (true)
  29. {
  30. byte k1 = rand() % 0xFF;
  31. byte k7 = rand() % 0xFF;
  32. byte k2 = rand() % 0xFF;
  33. byte k5 = rand() % 0xFF;
  34. DWORD ESI = (0X100 * (k1 ^ k7 & 0XFF) + k2 ^ k5 & 0XFF) & 0XFFFF;
  35. DWORD EAX = (((ESI ^ 0x7892) + 0x4d30) ^ 0x3421) & 0xffff;
  36. if (EAX%0XB == 0 && EAX / 0XB <= 0X3E8)
  37. {
  38. K[1] = k1;
  39. K[7] = k7;
  40. K[2] = k2;
  41. K[5] = k5;
  42. break;
  43. }
  44. }
  45. printf("%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X", K[0], K[1], K[2], K[3], K[4], K[5], K[6], K[7], K[8], K[9]);
  46. }

image.png

image.png
image.png

继续分析并写出完整密钥算法

image.png

  1. #include <iostream>
  2. #include <Windows.h>
  3. #include <time.h>
  4. int main()
  5. {
  6. srand(time(NULL));
  7. byte K[10] = { 0x11, 0x22, 0x33 ,0x9C, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA };
  8. //第一个call关系:
  9. //al = (k0^k6 ^ 0X18 + 0X3D) ^ 0XA7;
  10. //判断al大于0才是正确密钥
  11. while (true)
  12. {
  13. byte k0 = rand() % 0xFF;
  14. byte k6 = K[6];
  15. byte al = (k0^k6 ^ 0X18 + 0X3D) ^ 0XA7;
  16. if (al>=9)
  17. {
  18. K[0] = k0;
  19. K[6] = k6;
  20. break;
  21. }
  22. }
  23. //第二个call关系:
  24. //ESI = (0X100 * (k1 ^ k7 & 0XFF) + k2 ^ k5 & 0XFF) & 0XFFFF;
  25. //EAX = (((ESI ^ 0x7892) + 0x4d30) ^ 0x3421) & 0xffff;
  26. //如果没有余数,则返回商;有余数,则返回0
  27. //没有余数才是正确的,并且商必须小于等于0x3E8
  28. while (true)
  29. {
  30. byte k1 = rand() % 0xFF;
  31. byte k7 = rand() % 0xFF;
  32. byte k2 = rand() % 0xFF;
  33. byte k5 = rand() % 0xFF;
  34. DWORD ESI = (0X100 * (k1 ^ k7 & 0XFF) + k2 ^ k5 & 0XFF) & 0XFFFF;
  35. DWORD EAX = (((ESI ^ 0x7892) + 0x4d30) ^ 0x3421) & 0xffff;
  36. if (EAX%0XB == 0 && EAX / 0XB <= 0X3E8)
  37. {
  38. K[1] = k1;
  39. K[7] = k7;
  40. K[2] = k2;
  41. K[5] = k5;
  42. break;
  43. }
  44. }
  45. //用户名,加密
  46. DWORD daKey = EncodeUsername("www.15pb.com.cn", 1, 0, 0X3E8);
  47. K[4] = daKey & 0xFF;
  48. K[5] = daKey >> 8 & 0xFF;
  49. K[6] = daKey >> 16 & 0xFF;
  50. K[7] = daKey >> 24 & 0xFF;
  51. printf("%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X", K[0], K[1], K[2], K[3], K[4], K[5], K[6], K[7], K[8], K[9]);
  52. }

IDA分析并写C代码—对用户名加密的函数

image.png
image.png
image.png
image.png
image.png
写加密函数

  1. DWORD g_EcodeArray[]={
  2. 0x63866e1b, 0x3f920e3c, 0x55023490, 0x55b56089, 0x2c391fd1, 0x2f8035c2, 0x64fd2b7a, 0x4ce8759a, 0x518504f0, 0x799501a8, 0x3f5b2cad, 0x38e60160, 0x637641d8, 0x33352a42, 0x51a22c19, 0x085c5851,
  3. 0x032917ab, 0x2b770ac7, 0x30ac77b3, 0x2bec1907, 0x035202d0, 0x0fa933d3, 0x61255df3, 0x22ad06bf, 0x58b86971, 0x5fca0de5, 0x700d6456, 0x56a973db, 0x5ab759fd, 0x330e0be2, 0x5b3c0ddd, 0x495d3c60,
  4. 0x53bd59a6, 0x4c5e6d91, 0x49d9318d, 0x103d5079, 0x61ce42e3, 0x7ed5121d, 0x14e160ed, 0x212d4ef2, 0x270133f0, 0x62435a96, 0x1fa75e8b, 0x6f092fbe, 0x4a000d49, 0x57ae1c70, 0x004e2477, 0x561e7e72,
  5. 0x468c0033, 0x5dcc2402, 0x78507ac6, 0x58af24c7, 0x0df62d34, 0x358a4708, 0x3cfb1e11, 0x2b71451c, 0x77a75295, 0x56890721, 0x0fef75f3, 0x120f24f1, 0x01990ae7, 0x339c4452, 0x27a15b8e, 0x0ba7276d,
  6. 0x60dc1b7b, 0x4f4b7f82, 0x67db7007, 0x4f4a57d9, 0x621252e8, 0x20532cfc, 0x6a390306, 0x18800423, 0x19f3778a, 0x462316f0, 0x56ae0937, 0x43c2675c, 0x65ca45fd, 0x0d604ff2, 0x0bfd22cb, 0x3afe643b,
  7. 0x3bf67fa6, 0x44623579, 0x184031f8, 0x32174f97, 0x4c6a092a, 0x5fb50261, 0x01650174, 0x33634af1, 0x712d18f4, 0x6e997169, 0x5dab7afe, 0x7c2b2ee8, 0x6edb75b4, 0x5f836fb6, 0x3c2a6dd6, 0x292d05c2,
  8. 0x052244db, 0x149a5f4f, 0x5d486540, 0x331d15ea, 0x4f456920, 0x483a699f, 0x3b450f05, 0x3b207c6c, 0x749d70fe, 0x417461f6, 0x62b031f1, 0x2750577b, 0x29131533, 0x588c3808, 0x1aef3456, 0x0f3c00ec,
  9. 0x7da74742, 0x4b797a6c, 0x5ebb3287, 0x786558b8, 0x00ed4ff2, 0x6269691e, 0x24a2255f, 0x62c11f7e, 0x2f8a7dcd, 0x643b17fe, 0x778318b8, 0x253b60fe, 0x34bb63a3, 0x5b03214f, 0x5f1571f4, 0x1a316e9f,
  10. 0x7acf2704, 0x28896838, 0x18614677, 0x1bf569eb, 0x0ba85ec9, 0x6aca6b46, 0x1e43422a, 0x514d5f0e, 0x413e018c, 0x307626e9, 0x01ed1dfa, 0x49f46f5a, 0x461b642b, 0x7d7007f2, 0x13652657, 0x6b160bc5,
  11. 0x65e04849, 0x1f526e1c, 0x5a0251b6, 0x2bd73f69, 0x2dbf7acd, 0x51e63e80, 0x5cf2670f, 0x21cd0a03, 0x5cff0261, 0x33ae061e, 0x3bb6345f, 0x5d814a75, 0x257b5df4, 0x0a5c2c5b, 0x16a45527, 0x16f23945
  12. };
  13. int __cdecl EncodeUsername(const char *a1, int a2, char a3, char a4)
  14. {
  15. const char *v4; // edx@1
  16. signed int v5; // esi@1
  17. signed int v6; // edi@1
  18. unsigned __int8 v7; // bl@2
  19. int v8; // eax@3
  20. int v9; // ecx@3
  21. int v10; // ecx@4
  22. int result; // eax@4
  23. int v12; // ecx@5
  24. unsigned __int8 v13; // [sp+8h] [bp-10h]@2
  25. unsigned __int8 v14; // [sp+Ch] [bp-Ch]@2
  26. unsigned __int8 v15; // [sp+10h] [bp-8h]@2
  27. int v16; // [sp+14h] [bp-4h]@1
  28. v4 = a1;
  29. v16 = 0;
  30. v5 = strlen(a1);
  31. v6 = 0;
  32. if ( v5 <= 0 )
  33. {
  34. result = 0;
  35. }
  36. else
  37. {
  38. v13 = 0;
  39. v14 = 0;
  40. v7 = 15 * a4;
  41. v15 = 17 * a3;
  42. do
  43. {
  44. v8 = toupper(v4[v6]);
  45. v9 = v16 + g_EcodeArray[v8];
  46. if ( a2 )
  47. {
  48. v10 = g_EcodeArray[v7]
  49. + g_EcodeArray[v15]
  50. + g_EcodeArray[(unsigned __int8)(v8 + 47)] * (g_EcodeArray[(unsigned __int8)(v8 + 13)] ^ v9);
  51. result = g_EcodeArray[v14] + v10;
  52. v16 = g_EcodeArray[v14] + v10;
  53. }
  54. else
  55. {
  56. v12 = g_EcodeArray[v7]
  57. + g_EcodeArray[v15]
  58. + g_EcodeArray[(unsigned __int8)(v8 + 23)] * (g_EcodeArray[(unsigned __int8)(v8 + 63)] ^ v9);
  59. result = g_EcodeArray[v13] + v12;
  60. v16 = g_EcodeArray[v13] + v12;
  61. }
  62. v14 += 19;
  63. ++v6;
  64. v15 += 9;
  65. v7 += 13;
  66. v13 += 7;
  67. v4 = a1;
  68. }
  69. while ( v6 < v5 );
  70. }
  71. return result;
  72. }

结合OD完整写好C代码—对用户名加密函数

根据OD分析更改一下参数
image.png
发现第一个参数为”www.15pb.com.cn”,第二个参数为1,第二个参数为0,第四个参数为第二个call关系的返回值
image.png

  1. int __cdecl EncodeUsername(const char *pstrUsername, int a2, char a3, unsigned __int16 a4)
  2. {
  3. const char *v4; // edx@1
  4. signed int v5; // esi@1
  5. signed int v6; // edi@1
  6. unsigned __int8 v7; // bl@2
  7. int v8; // eax@3
  8. int v9; // ecx@3
  9. int v10; // ecx@4
  10. int result; // eax@4
  11. int v12; // ecx@5
  12. unsigned __int8 v13; // [sp+8h] [bp-10h]@2
  13. unsigned __int8 v14; // [sp+Ch] [bp-Ch]@2
  14. unsigned __int8 v15; // [sp+10h] [bp-8h]@2
  15. int v16; // [sp+14h] [bp-4h]@1
  16. v4 = pstrUsername;
  17. v16 = 0;
  18. v5 = strlen(pstrUsername);
  19. v6 = 0;
  20. if (v5 <= 0)
  21. {
  22. result = 0;
  23. }
  24. else
  25. {
  26. v13 = 0;
  27. v14 = 0;
  28. v7 = 15 * a4;
  29. v15 = 17 * a3;
  30. do
  31. {
  32. v8 = toupper(v4[v6]);
  33. v9 = v16 + g_EcodeArray[v8];
  34. if (a2)
  35. {
  36. v10 = g_EcodeArray[v7]
  37. + g_EcodeArray[v15]
  38. + g_EcodeArray[(unsigned __int8)(v8 + 47)] * (g_EcodeArray[(unsigned __int8)(v8 + 13)] ^ v9);
  39. result = g_EcodeArray[v14] + v10;
  40. v16 = g_EcodeArray[v14] + v10;
  41. }
  42. else
  43. {
  44. v12 = g_EcodeArray[v7]
  45. + g_EcodeArray[v15]
  46. + g_EcodeArray[(unsigned __int8)(v8 + 23)] * (g_EcodeArray[(unsigned __int8)(v8 + 63)] ^ v9);
  47. result = g_EcodeArray[v13] + v12;
  48. v16 = g_EcodeArray[v13] + v12;
  49. }
  50. v14 += 19;
  51. ++v6;
  52. v15 += 9;
  53. v7 += 13;
  54. v13 += 7;
  55. v4 = pstrUsername;
  56. } while (v6 < v5);
  57. }
  58. return result;
  59. }

完善C代码注册机

主要是调整代码的逻辑关系

  1. // 010EDITOR.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
  2. //
  3. #include "pch.h"
  4. #include <iostream>
  5. #include <Windows.h>
  6. #include <time.h>
  7. DWORD g_EcodeArray[]={
  8. 0x39cb44b8, 0x23754f67, 0x5f017211, 0x3ebb24da, 0x351707c6, 0x63f9774b, 0x17827288, 0x0fe74821, 0x5b5f670f, 0x48315ae8, 0x785b7769, 0x2b7a1547, 0x38d11292, 0x42a11b32, 0x35332244, 0x77437b60,
  9. 0x1eab3b10, 0x53810000, 0x1d0212ae, 0x6f0377a8, 0x43c03092, 0x2d3c0a8e, 0x62950cbf, 0x30f06ffa, 0x34f710e0, 0x28f417fb, 0x350d2f95, 0x5a361d5a, 0x15cc060b, 0x0afd13cc, 0x28603bcf, 0x3371066b,
  10. 0x30cd14e4, 0x175d3a67, 0x6dd66a13, 0x2d3409f9, 0x581e7b82, 0x76526b99, 0x5c8d5188, 0x2c857971, 0x15f51fc0, 0x68cc0d11, 0x49f55e5c, 0x275e4364, 0x2d1e0dbc, 0x4cee7ce3, 0x32555840, 0x112e2e08,
  11. 0x6978065a, 0x72921406, 0x314578e7, 0x175621b7, 0x40771dbf, 0x3fc238d6, 0x4a31128a, 0x2dad036e, 0x41a069d6, 0x25400192, 0x00dd4667, 0x6afc1f4f, 0x571040ce, 0x62fe66df, 0x41db4b3e, 0x3582231f,
  12. 0x55f6079a, 0x1ca70644, 0x1b1643d2, 0x3f7228c9, 0x5f141070, 0x3e1474ab, 0x444b256e, 0x537050d9, 0x0f42094b, 0x2fd820e6, 0x778b2e5e, 0x71176d02, 0x7fea7a69, 0x5bb54628, 0x19ba6c71, 0x39763a99,
  13. 0x178d54cd, 0x01246e88, 0x3313537e, 0x2b8e2d17, 0x2a3d10be, 0x59d10582, 0x37a163db, 0x30d6489a, 0x6a215c46, 0x0e1c7a76, 0x1fc760e7, 0x79b80c65, 0x27f459b4, 0x799a7326, 0x50ba1782, 0x2a116d5c,
  14. 0x63866e1b, 0x3f920e3c, 0x55023490, 0x55b56089, 0x2c391fd1, 0x2f8035c2, 0x64fd2b7a, 0x4ce8759a, 0x518504f0, 0x799501a8, 0x3f5b2cad, 0x38e60160, 0x637641d8, 0x33352a42, 0x51a22c19, 0x085c5851,
  15. 0x032917ab, 0x2b770ac7, 0x30ac77b3, 0x2bec1907, 0x035202d0, 0x0fa933d3, 0x61255df3, 0x22ad06bf, 0x58b86971, 0x5fca0de5, 0x700d6456, 0x56a973db, 0x5ab759fd, 0x330e0be2, 0x5b3c0ddd, 0x495d3c60,
  16. 0x53bd59a6, 0x4c5e6d91, 0x49d9318d, 0x103d5079, 0x61ce42e3, 0x7ed5121d, 0x14e160ed, 0x212d4ef2, 0x270133f0, 0x62435a96, 0x1fa75e8b, 0x6f092fbe, 0x4a000d49, 0x57ae1c70, 0x004e2477, 0x561e7e72,
  17. 0x468c0033, 0x5dcc2402, 0x78507ac6, 0x58af24c7, 0x0df62d34, 0x358a4708, 0x3cfb1e11, 0x2b71451c, 0x77a75295, 0x56890721, 0x0fef75f3, 0x120f24f1, 0x01990ae7, 0x339c4452, 0x27a15b8e, 0x0ba7276d,
  18. 0x60dc1b7b, 0x4f4b7f82, 0x67db7007, 0x4f4a57d9, 0x621252e8, 0x20532cfc, 0x6a390306, 0x18800423, 0x19f3778a, 0x462316f0, 0x56ae0937, 0x43c2675c, 0x65ca45fd, 0x0d604ff2, 0x0bfd22cb, 0x3afe643b,
  19. 0x3bf67fa6, 0x44623579, 0x184031f8, 0x32174f97, 0x4c6a092a, 0x5fb50261, 0x01650174, 0x33634af1, 0x712d18f4, 0x6e997169, 0x5dab7afe, 0x7c2b2ee8, 0x6edb75b4, 0x5f836fb6, 0x3c2a6dd6, 0x292d05c2,
  20. 0x052244db, 0x149a5f4f, 0x5d486540, 0x331d15ea, 0x4f456920, 0x483a699f, 0x3b450f05, 0x3b207c6c, 0x749d70fe, 0x417461f6, 0x62b031f1, 0x2750577b, 0x29131533, 0x588c3808, 0x1aef3456, 0x0f3c00ec,
  21. 0x7da74742, 0x4b797a6c, 0x5ebb3287, 0x786558b8, 0x00ed4ff2, 0x6269691e, 0x24a2255f, 0x62c11f7e, 0x2f8a7dcd, 0x643b17fe, 0x778318b8, 0x253b60fe, 0x34bb63a3, 0x5b03214f, 0x5f1571f4, 0x1a316e9f,
  22. 0x7acf2704, 0x28896838, 0x18614677, 0x1bf569eb, 0x0ba85ec9, 0x6aca6b46, 0x1e43422a, 0x514d5f0e, 0x413e018c, 0x307626e9, 0x01ed1dfa, 0x49f46f5a, 0x461b642b, 0x7d7007f2, 0x13652657, 0x6b160bc5,
  23. 0x65e04849, 0x1f526e1c, 0x5a0251b6, 0x2bd73f69, 0x2dbf7acd, 0x51e63e80, 0x5cf2670f, 0x21cd0a03, 0x5cff0261, 0x33ae061e, 0x3bb6345f, 0x5d814a75, 0x257b5df4, 0x0a5c2c5b, 0x16a45527, 0x16f23945
  24. };
  25. int __cdecl EncodeUsername(const char *pstrUsername, int a2, char a3, unsigned __int16 a4)
  26. {
  27. const char *v4; // edx@1
  28. signed int v5; // esi@1
  29. signed int v6; // edi@1
  30. unsigned __int8 v7; // bl@2
  31. int v8; // eax@3
  32. int v9; // ecx@3
  33. int v10; // ecx@4
  34. int result; // eax@4
  35. int v12; // ecx@5
  36. unsigned __int8 v13; // [sp+8h] [bp-10h]@2
  37. unsigned __int8 v14; // [sp+Ch] [bp-Ch]@2
  38. unsigned __int8 v15; // [sp+10h] [bp-8h]@2
  39. int v16; // [sp+14h] [bp-4h]@1
  40. v4 = pstrUsername;
  41. v16 = 0;
  42. v5 = strlen(pstrUsername);
  43. v6 = 0;
  44. if (v5 <= 0)
  45. {
  46. result = 0;
  47. }
  48. else
  49. {
  50. v13 = 0;
  51. v14 = 0;
  52. v7 = 15 * a4;
  53. v15 = 17 * a3;
  54. do
  55. {
  56. v8 = toupper(v4[v6]);
  57. v9 = v16 + g_EcodeArray[v8];
  58. if (a2)
  59. {
  60. v10 = g_EcodeArray[v7]
  61. + g_EcodeArray[v15]
  62. + g_EcodeArray[(unsigned __int8)(v8 + 47)] * (g_EcodeArray[(unsigned __int8)(v8 + 13)] ^ v9);
  63. result = g_EcodeArray[v14] + v10;
  64. v16 = g_EcodeArray[v14] + v10;
  65. }
  66. else
  67. {
  68. v12 = g_EcodeArray[v7]
  69. + g_EcodeArray[v15]
  70. + g_EcodeArray[(unsigned __int8)(v8 + 23)] * (g_EcodeArray[(unsigned __int8)(v8 + 63)] ^ v9);
  71. result = g_EcodeArray[v13] + v12;
  72. v16 = g_EcodeArray[v13] + v12;
  73. }
  74. v14 += 19;
  75. ++v6;
  76. v15 += 9;
  77. v7 += 13;
  78. v13 += 7;
  79. v4 = pstrUsername;
  80. } while (v6 < v5);
  81. }
  82. return result;
  83. }
  84. int main()
  85. {
  86. srand(time(NULL));
  87. int dwRet = 0X3E8;
  88. byte K[10] = { 0x11, 0x22, 0x33 ,0x9C, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA };
  89. //用户名,加密
  90. DWORD daKey = EncodeUsername("www.15pb.com.cn", 1, 0, dwRet);
  91. K[4] = daKey & 0xFF;
  92. K[5] = daKey >> 8 & 0xFF;
  93. K[6] = daKey >> 16 & 0xFF;
  94. K[7] = daKey >> 24 & 0xFF;
  95. while (true)
  96. {
  97. byte k0 = rand() % 0xFF;
  98. byte k6 = K[6];
  99. byte al = (k0^k6 ^ 0X18 + 0X3D) ^ 0XA7;
  100. if (al>=9)
  101. {
  102. K[0] = k0;
  103. K[6] = k6;
  104. break;
  105. }
  106. }
  107. while (true)
  108. {
  109. byte k1 = rand() % 0xFF;
  110. byte k7 = K[7];
  111. byte k2 = rand() % 0xFF;
  112. byte k5 = K[5];
  113. DWORD ESI = (0X100 * (k1 ^ k7 & 0XFF) + k2 ^ k5 & 0XFF) & 0XFFFF;
  114. DWORD EAX = (((ESI ^ 0x7892) + 0x4d30) ^ 0x3421) & 0xffff;
  115. if (EAX%0XB == 0 && EAX / 0XB == dwRet)
  116. {
  117. K[1] = k1;
  118. K[7] = k7;
  119. K[2] = k2;
  120. K[5] = k5;
  121. break;
  122. }
  123. }
  124. printf("%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X", K[0], K[1], K[2], K[3], K[4], K[5], K[6], K[7], K[8], K[9]);
  125. }