На прошлом уроке мы поняли как формируется activation code, и столкнулись с RSA шифрованием. Так как у нас нет приватного ключа, мы не можем создать валидные данные для активации, то создадим свою ключевую пару.
Для начала посмотрим характеристики ключа который зашит в программе, он в формате PEM, скармливаем его утилите openssl
openssl rsa -inform PEM -in pk.pem -pubin -text
rsa ключ 2048 бит, генерируем свою ключевую пару на pythonCode:Modulus (2048 bit): 00:ef:6e:b9:30:55:89:ae:ad:4e:9f:a5:d1:a9:ad: a9:10:cd:19:ae:ac:fe:ee:61:83:03:1f:77:8b:da: 31:6a:37:45:6d:89:a6:12:26:99:83:ca:4b:a2:0e: 86:b8:b7:8e:9b:63:58:d1:7c:5c:28:e1:da:45:c1: 51:da:c8:84:50:8c:1e:80:3d:9e:18:d8:0e:da:17: 76:ae:75:94:d4:07:ef:09:06:8e:83:52:5c:09:b1: 16:d0:52:e8:38:fa:03:69:93:32:87:c2:21:09:67: fa:03:27:80:b3:95:34:60:7f:d3:2c:49:80:bc:26: 83:c5:d5:3a:4c:48:3c:cf:2d:82:db:71:a8:02:85: 2f:71:9d:d2:49:02:4d:5b:3d:0d:a9:14:8d:9d:5e: fc:c1:99:87:ca:83:74:b9:0f:32:c8:c8:2b:31:84: 35:db:e0:d9:fc:98:5e:ff:6c:12:38:f2:0e:67:00: e4:0b:02:ed:ce:d7:2f:12:c2:67:27:88:b6:e3:fa: 3d:25:40:f5:9c:ca:4d:43:ce:32:01:33:c4:b3:75: b1:98:00:66:ac:c2:f2:40:ba:16:e0:1b:85:c1:7c: 66:0c:11:fa:f7:c4:92:2c:6f:01:fb:37:d9:35:38: 42:c8:5b:2c:59:3d:be:6b:76:a8:41:10:44:f0:b8: 08:35 Exponent: 65537 (0x10001) writing RSA key -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7265MFWJrq1On6XRqa2p EM0Zrqz+7mGDAx93i9oxajdFbYmmEiaZg8pLog6GuLeOm2NY0XxcKOHaRcFR2siE UIwegD2eGNgO2hd2rnWU1AfvCQaOg1JcCbEW0FLoOPoDaZMyh8IhCWf6AyeAs5U0 YH/TLEmAvCaDxdU6TEg8zy2C23GoAoUvcZ3SSQJNWz0NqRSNnV78wZmHyoN0uQ8y yMgrMYQ12+DZ/Jhe/2wSOPIOZwDkCwLtztcvEsJnJ4i24/o9JUD1nMpNQ84yATPE s3WxmABmrMLyQLoW4BuFwXxmDBH698SSLG8B+zfZNThCyFssWT2+a3aoQRBE8LgI NQIDAQAB -----END PUBLIC KEY-----
у меня получились такие ключикиCode:import struct import base64 import json from Crypto.PublicKey import RSA as CryptoRSA def genRSA(): rsa=CryptoRSA.generate(2048) priv=rsa.exportKey() pub=rsa.publickey().exportKey(format='PEM') return priv,pub if __name__=="__main__": priv,pub=genRSA() print priv print pub
далее нужно пропатчить pas2.dll нашим публичным ключиком, при этом не забываем что он должен быть зашифрован DES ECB, кроме того длинна шифрованных данных должна быть кратна 8, недостающие байты забиваем нулямиCode:-----BEGIN RSA PRIVATE KEY----- MIIEpgIBAAKCAQEAwOY9lw75taUd7EH7XKOgh+P7kKGMZNglOZNfBhNnC35vzThT LJLjZjVlassbRDDtLNHfxtDvq745R+19sQdMKXzkka/0O6dcjDrOeK3ZGRXGVqCk iTf4pvK+jJU/PzU8NRyThRawXUxJRZ4wx7brTuE7gho2eQXB1+3xXGKfYYxofPzf doEvB0y08843FQVX1iJNmb3gJqnAQzo3LSOH3yjnRv48pA1Fa6UmrZJ/Ppc0Okp1 WpPEP3TPB3Vi5iR4b5SlKD48+jrCY2AEm1g7JjA3V4MaHYqWdr9H6ltpiFF9+ziW 9zeIdL277JPDOsMt4g7yU0Ez+WZefSdsvEF9bQIDAQABAoIBAQCcuPOFTXd4K0Ta dOlCZPbCMWpsIbStIidsVd24U/8+iWVQeNiquFTk77EMSSRIDPBFn+aN46c2BAEJ /VxHfkRU2NHjw+9MoDdC/2xNBAIErXpNW4sSqVTuXv6NvZx7QEdAZ407bimwQ5Cs bU/4kxcvKTNuCtoDDbhmNT4J717KoxuDzEviJRlmLxVf4nq97ahyUA1t89Hss2NF RLHC3inkXyTw9wn1gE9i+Xi77ZH/eanldRZkc4PczHJxGdFVuJX0rIhNsG0Fs9rI OFn7WCUrYzAKF8qq0+7clpmDCZSai+i5BxVt/hgLME5nva2KPvIlMINcPeO+rc5x NM5nKiCJAoGBAMVTTJVm704QRfl8YNwFu0dI/jIg+EAR8gS4GUPek6sjszd4KcWq xc6LFbOm3NvNP96nbGHvijQuzwTrixr2o3DDM+CywvY1/ioBhBtDNxnuKsXpTZZM UtQ3kmDyNdUbisGzmEd+eGNu/odqyWbgWJXUT3b0ENy2FXGxC6S1eS43AoGBAPpC BujTA8eLW0G+6Uy2CLbYn0u+JzdTEcs2x5EuKEIvd/z7vsRlqqMLtjFLvU/qU/2z Gralyj3W2wG1nyHA73L6oOtB47qWbE5l+o5QPm+jMld9nUFq5M4jkjkNEzSwn19D Hgsx16oi/JgO/076YbAaHspheyHYQa27fIvmPX97AoGBAK3o3HZQYljKvuFDXZqM 8qHBE0fbBvBw4HyIRLwsTrlmnW0l2qr795oxus67IawXGVOC+2LVW1jiaFJNxivd c+7OG8rNwkZ9D6S18ViVxNp1rfz/wgHVAqtGzxviXM+VlpVhU7SvIiuAh5OR6i9h SrHCjMaqFLJxSDULdNeVmVfBAoGBAKyad4uDZprtOb6pvt0iu/XoiE3EU+XrjF09 Zf1y+V9UwAwjUZrBiCQ2Qq3TUDnbI5zaN/V7eXaXRqvyKVQtbrk9tVktM7UQZJjZ 6yrWm4mB5InFYH2rDS5ECGkC5Jk1rGYWs5UDBn0Y7mCuD1bYiCHekhgBjdx0/C+o HSmcXhQbAoGBAJO+os0qCqf7dcLSllh2LlDzxlnwuiBH854gLcF3vvG7PiIBY93d 81+nlSCz9AaokjPpctUTOoiNjmpjGEEQ+L9YdF2pbjrvLLT8Kbb4Z58jR6xCDuMq f0jALcFhzF1BA1MB/zZBd+HTNU//8XFj1p5DzFgAu5z6trZAIWnNgDNG -----END RSA PRIVATE KEY----- -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwOY9lw75taUd7EH7XKOg h+P7kKGMZNglOZNfBhNnC35vzThTLJLjZjVlassbRDDtLNHfxtDvq745R+19sQdM KXzkka/0O6dcjDrOeK3ZGRXGVqCkiTf4pvK+jJU/PzU8NRyThRawXUxJRZ4wx7br TuE7gho2eQXB1+3xXGKfYYxofPzfdoEvB0y08843FQVX1iJNmb3gJqnAQzo3LSOH 3yjnRv48pA1Fa6UmrZJ/Ppc0Okp1WpPEP3TPB3Vi5iR4b5SlKD48+jrCY2AEm1g7 JjA3V4MaHYqWdr9H6ltpiFF9+ziW9zeIdL277JPDOsMt4g7yU0Ez+WZefSdsvEF9 bQIDAQAB -----END PUBLIC KEY-----
код который патчит длл будет таким
подкладываем модифицированную pas2.dll программеCode:import struct import base64 import json from Crypto.Cipher import DES from Crypto.PublicKey import RSA as CryptoRSA def decodeDES(data): des=DES.new('7FB45FAB') dec=des.decrypt(data) return dec def encodeDES(data): des=DES.new('7FB45FAB') l=len(data) pad='\x00'*(8-(l-((l/8)*8))) enc=data+pad dec=des.encrypt(enc) return dec def genPatchData(priv,data): sig='\xC5\x03\x15\x61\xAD\xA9\x7E\x98' size=0x1C8 i=data.find(sig) if i==-1: raise Exception('error sign') a=CryptoRSA.importKey(priv) p=a.publickey() pub=p.exportKey() enc=encodeDES(pub) patch=data[:i]+enc+data[i+size:] return patch priv="""-----BEGIN RSA PRIVATE KEY----- MIIEpgIBAAKCAQEAwOY9lw75taUd7EH7XKOgh+P7kKGMZNglOZNfBhNnC35vzThT LJLjZjVlassbRDDtLNHfxtDvq745R+19sQdMKXzkka/0O6dcjDrOeK3ZGRXGVqCk iTf4pvK+jJU/PzU8NRyThRawXUxJRZ4wx7brTuE7gho2eQXB1+3xXGKfYYxofPzf doEvB0y08843FQVX1iJNmb3gJqnAQzo3LSOH3yjnRv48pA1Fa6UmrZJ/Ppc0Okp1 WpPEP3TPB3Vi5iR4b5SlKD48+jrCY2AEm1g7JjA3V4MaHYqWdr9H6ltpiFF9+ziW 9zeIdL277JPDOsMt4g7yU0Ez+WZefSdsvEF9bQIDAQABAoIBAQCcuPOFTXd4K0Ta dOlCZPbCMWpsIbStIidsVd24U/8+iWVQeNiquFTk77EMSSRIDPBFn+aN46c2BAEJ /VxHfkRU2NHjw+9MoDdC/2xNBAIErXpNW4sSqVTuXv6NvZx7QEdAZ407bimwQ5Cs bU/4kxcvKTNuCtoDDbhmNT4J717KoxuDzEviJRlmLxVf4nq97ahyUA1t89Hss2NF RLHC3inkXyTw9wn1gE9i+Xi77ZH/eanldRZkc4PczHJxGdFVuJX0rIhNsG0Fs9rI OFn7WCUrYzAKF8qq0+7clpmDCZSai+i5BxVt/hgLME5nva2KPvIlMINcPeO+rc5x NM5nKiCJAoGBAMVTTJVm704QRfl8YNwFu0dI/jIg+EAR8gS4GUPek6sjszd4KcWq xc6LFbOm3NvNP96nbGHvijQuzwTrixr2o3DDM+CywvY1/ioBhBtDNxnuKsXpTZZM UtQ3kmDyNdUbisGzmEd+eGNu/odqyWbgWJXUT3b0ENy2FXGxC6S1eS43AoGBAPpC BujTA8eLW0G+6Uy2CLbYn0u+JzdTEcs2x5EuKEIvd/z7vsRlqqMLtjFLvU/qU/2z Gralyj3W2wG1nyHA73L6oOtB47qWbE5l+o5QPm+jMld9nUFq5M4jkjkNEzSwn19D Hgsx16oi/JgO/076YbAaHspheyHYQa27fIvmPX97AoGBAK3o3HZQYljKvuFDXZqM 8qHBE0fbBvBw4HyIRLwsTrlmnW0l2qr795oxus67IawXGVOC+2LVW1jiaFJNxivd c+7OG8rNwkZ9D6S18ViVxNp1rfz/wgHVAqtGzxviXM+VlpVhU7SvIiuAh5OR6i9h SrHCjMaqFLJxSDULdNeVmVfBAoGBAKyad4uDZprtOb6pvt0iu/XoiE3EU+XrjF09 Zf1y+V9UwAwjUZrBiCQ2Qq3TUDnbI5zaN/V7eXaXRqvyKVQtbrk9tVktM7UQZJjZ 6yrWm4mB5InFYH2rDS5ECGkC5Jk1rGYWs5UDBn0Y7mCuD1bYiCHekhgBjdx0/C+o HSmcXhQbAoGBAJO+os0qCqf7dcLSllh2LlDzxlnwuiBH854gLcF3vvG7PiIBY93d 81+nlSCz9AaokjPpctUTOoiNjmpjGEEQ+L9YdF2pbjrvLLT8Kbb4Z58jR6xCDuMq f0jALcFhzF1BA1MB/zZBd+HTNU//8XFj1p5DzFgAu5z6trZAIWnNgDNG -----END RSA PRIVATE KEY-----""" if __name__=="__main__": data=open('x64\\Pas2.dll','rb').read() o=genPatchData(priv, data) open('x64\\Pas2.dll.patched','wb+').write(o) print 'done'
теперь можно шифровать запросы самостоятельно, напомню что формат сообщения выглядит так
base64_encode(json_encode([base64_encode(data1),base64_encode(data2)]))
исследуем функцию которая занимается расшифровкой данных
видим что данные извлекаются из json массива, выполняется base64_decode и передаются RSA_public_decrypt, расшифрованные данные соединяются вместе append
напишем код на python который зашифрует данные rsa
Code:import struct import base64 import json from Crypto.Cipher import DES from M2Crypto import RSA from Crypto.PublicKey import RSA as CryptoRSA def decodeRSA(priv,license): txt='' js=json.loads(license.decode('base64')) for i in js: t=i.decode('base64') rsa=RSA.load_key_string(priv) msg=rsa.private_decrypt(t,1) txt+=msg return json.loads(txt) def encodeRSA(priv,resp): js=json.dumps(resp) ls=[] while len(js)>0: t=js[:0x90] js=js[0x90:] rsa=RSA.load_key_string(priv) msg=rsa.private_encrypt(t,1) ls.append(base64.b64encode(msg)) return base64.b64encode(json.dumps(ls)) def decodeRSA(priv,license): txt='' js=json.loads(license.decode('base64')) for i in js: t=i.decode('base64') rsa=RSA.load_key_string(priv) msg=rsa.private_decrypt(t,1) txt+=msg return json.loads(txt) priv="""-----BEGIN RSA PRIVATE KEY----- MIIEpgIBAAKCAQEAwOY9lw75taUd7EH7XKOgh+P7kKGMZNglOZNfBhNnC35vzThT LJLjZjVlassbRDDtLNHfxtDvq745R+19sQdMKXzkka/0O6dcjDrOeK3ZGRXGVqCk iTf4pvK+jJU/PzU8NRyThRawXUxJRZ4wx7brTuE7gho2eQXB1+3xXGKfYYxofPzf doEvB0y08843FQVX1iJNmb3gJqnAQzo3LSOH3yjnRv48pA1Fa6UmrZJ/Ppc0Okp1 WpPEP3TPB3Vi5iR4b5SlKD48+jrCY2AEm1g7JjA3V4MaHYqWdr9H6ltpiFF9+ziW 9zeIdL277JPDOsMt4g7yU0Ez+WZefSdsvEF9bQIDAQABAoIBAQCcuPOFTXd4K0Ta dOlCZPbCMWpsIbStIidsVd24U/8+iWVQeNiquFTk77EMSSRIDPBFn+aN46c2BAEJ /VxHfkRU2NHjw+9MoDdC/2xNBAIErXpNW4sSqVTuXv6NvZx7QEdAZ407bimwQ5Cs bU/4kxcvKTNuCtoDDbhmNT4J717KoxuDzEviJRlmLxVf4nq97ahyUA1t89Hss2NF RLHC3inkXyTw9wn1gE9i+Xi77ZH/eanldRZkc4PczHJxGdFVuJX0rIhNsG0Fs9rI OFn7WCUrYzAKF8qq0+7clpmDCZSai+i5BxVt/hgLME5nva2KPvIlMINcPeO+rc5x NM5nKiCJAoGBAMVTTJVm704QRfl8YNwFu0dI/jIg+EAR8gS4GUPek6sjszd4KcWq xc6LFbOm3NvNP96nbGHvijQuzwTrixr2o3DDM+CywvY1/ioBhBtDNxnuKsXpTZZM UtQ3kmDyNdUbisGzmEd+eGNu/odqyWbgWJXUT3b0ENy2FXGxC6S1eS43AoGBAPpC BujTA8eLW0G+6Uy2CLbYn0u+JzdTEcs2x5EuKEIvd/z7vsRlqqMLtjFLvU/qU/2z Gralyj3W2wG1nyHA73L6oOtB47qWbE5l+o5QPm+jMld9nUFq5M4jkjkNEzSwn19D Hgsx16oi/JgO/076YbAaHspheyHYQa27fIvmPX97AoGBAK3o3HZQYljKvuFDXZqM 8qHBE0fbBvBw4HyIRLwsTrlmnW0l2qr795oxus67IawXGVOC+2LVW1jiaFJNxivd c+7OG8rNwkZ9D6S18ViVxNp1rfz/wgHVAqtGzxviXM+VlpVhU7SvIiuAh5OR6i9h SrHCjMaqFLJxSDULdNeVmVfBAoGBAKyad4uDZprtOb6pvt0iu/XoiE3EU+XrjF09 Zf1y+V9UwAwjUZrBiCQ2Qq3TUDnbI5zaN/V7eXaXRqvyKVQtbrk9tVktM7UQZJjZ 6yrWm4mB5InFYH2rDS5ECGkC5Jk1rGYWs5UDBn0Y7mCuD1bYiCHekhgBjdx0/C+o HSmcXhQbAoGBAJO+os0qCqf7dcLSllh2LlDzxlnwuiBH854gLcF3vvG7PiIBY93d 81+nlSCz9AaokjPpctUTOoiNjmpjGEEQ+L9YdF2pbjrvLLT8Kbb4Z58jR6xCDuMq f0jALcFhzF1BA1MB/zZBd+HTNU//8XFj1p5DzFgAu5z6trZAIWnNgDNG -----END RSA PRIVATE KEY-----""" if __name__=="__main__": activation_code=encodeRSA(priv,{}) print activation_code
я использовал M2Crypto через pip она у меня не поставилась и я взял готовую сборку для windows
https://github.com/dsoprea/M2CryptoWindows
результатом будет такой activation code
подставляем его в программу и смотрим корректность расшифровки в отладчикеCode:WyJBVzMzQlh4bENlVjRPR09rSFdldmxOWnFaVnFlVW1GVHcvNjBvSGM1K0FQTGRLTFBJWWJJeDdraDQ1RDlXZnUrK1RLNVZJeUtxUjAwWVhXa2RYa1g1Vm9TMXpUS3I4Wm05U00xSC9mUmtVNEhJV3diTDFkdjY0Y0tQNmZVTGFJT3lRMW9HNWtoM3JyeVFKZENOSUdzQ21VcDNrSlVMTm5JQmt4MEFFaUVtU29MamtzdDJxTWJSckxGY0RuMDNWSWRxb1kyMVIrc1YrWnlMMVNHcU52amxoRm5SRGJzMW1NUDk2cklKYTlIYnhMSmlNZXVIMWhsZHJxMTgxYS9mcGEzR1JCSHd5aGx6QnZyYTdDUjBlY0t3Z3Z0MllaUUwxZ29KUDA0c2thR3BpaytudklqcWlybVBuMFM3Y25xZDJhejRxTjRKWVJsK01UT1QwTUpSNnJRZ1E9PSJd
я решил посмотреть перекрестные ссылки на функцию RSA шифрования
исследовав код можно понять что он принадлежит License Information, для расшифровки данных можно воспользоватся decodeRSA
в результате получим такое
вернемся обратно к activation code, мы научились шифровать и расшифровывать запрос, но что лежит в полезной нагрузке пока не ясноCode:{ "LicenseCode": "123456-78A8E7-04D461-0D7679", "MachineCode": "1ae6c86a10b1210fd3f1aa6942cf41b6", "MachineInfo": "Motherboard Info: innotek gmbh|default system bios|0|\nCpuName:Intel(R) Core(TM) i5-4570R CPU @ 2.70GHz (3)", "VersionCode": "54143fe13d7deb6f918fb25bd4d8b4fc" }
для этого продолжим отладку
тут мы успешно прошли процедуру шифрования
далее идет валидация параметров json, то что мы зашифровали RSA
формируем такой jsonCode:.text:000007FEEEE0FF44 lea rdx, [rsp+130h+var_F8] .text:000007FEEEE0FF49 lea rcx, [rsp+130h+var_108] .text:000007FEEEE0FF4E call cs:?toUtf8@QString@@QEBA?AVQByteArray@@XZ ; QString::toUtf8(void) .text:000007FEEEE0FF54 nop .text:000007FEEEE0FF55 .text:000007FEEEE0FF55 loc_7FEEEE0FF55: ; DATA XREF: .rdata:000007FEEEE2B7F0↓o .text:000007FEEEE0FF55 xor r8d, r8d .text:000007FEEEE0FF58 mov rdx, rax .text:000007FEEEE0FF5B lea rcx, [rsp+130h+var_110] .text:000007FEEEE0FF60 call cs:?fromJson@QJsonDocument@@SA?AV1@AEBVQByteArray@@PEAUQJsonParseError@@@Z ; QJsonDocument::fromJson(QByteArray const &,QJsonParseError *) .text:000007FEEEE0FF66 nop .text:000007FEEEE0FF67 .text:000007FEEEE0FF67 loc_7FEEEE0FF67: ; DATA XREF: .rdata:000007FEEEE2B7F8↓o .text:000007FEEEE0FF67 lea rdx, [rsp+130h+var_E0] .text:000007FEEEE0FF6C mov rcx, rax .text:000007FEEEE0FF6F call cs:?object@QJsonDocument@@QEBA?AVQJsonObject@@XZ ; QJsonDocument::object(void) .text:000007FEEEE0FF75 nop .text:000007FEEEE0FF76 .text:000007FEEEE0FF76 loc_7FEEEE0FF76: ; DATA XREF: .rdata:000007FEEEE2B800↓o .text:000007FEEEE0FF76 mov rdx, rax .text:000007FEEEE0FF79 lea rcx, [rsp+130h+var_F0] .text:000007FEEEE0FF7E call cs:??4QJsonObject@@QEAAAEAV0@AEBV0@@Z ; QJsonObject::operator=(QJsonObject const &) .text:000007FEEEE0FF84 nop .text:000007FEEEE0FF85 .text:000007FEEEE0FF85 loc_7FEEEE0FF85: ; DATA XREF: .rdata:000007FEEEE2B808↓o .text:000007FEEEE0FF85 lea rcx, [rsp+130h+var_E0] .text:000007FEEEE0FF8A call cs:??1QJsonObject@@QEAA@XZ ; QJsonObject::~QJsonObject(void) .text:000007FEEEE0FF90 nop .text:000007FEEEE0FF91 .text:000007FEEEE0FF91 loc_7FEEEE0FF91: ; DATA XREF: .rdata:000007FEEEE2B810↓o .text:000007FEEEE0FF91 lea rcx, [rsp+130h+var_110] .text:000007FEEEE0FF96 call cs:??1QJsonDocument@@QEAA@XZ ; QJsonDocument::~QJsonDocument(void) .text:000007FEEEE0FF9C nop .text:000007FEEEE0FF9D .text:000007FEEEE0FF9D loc_7FEEEE0FF9D: ; DATA XREF: .rdata:000007FEEEE2B818↓o .text:000007FEEEE0FF9D lea rcx, [rsp+130h+var_F8] .text:000007FEEEE0FFA2 call cs:??1QByteArray@@QEAA@XZ ; QByteArray::~QByteArray(void) .text:000007FEEEE0FFA8 lea rcx, [rsp+130h+var_F0] .text:000007FEEEE0FFAD call cs:?isEmpty@QJsonObject@@QEBA_NXZ ; QJsonObject::isEmpty(void) .text:000007FEEEE0FFB3 test al, al .text:000007FEEEE0FFB5 setz bl .text:000007FEEEE0FFB8 .text:000007FEEEE0FFB8 loc_7FEEEE0FFB8: ; DATA XREF: .rdata:000007FEEEE2B820↓o .text:000007FEEEE0FFB8 lea rcx, [rsp+130h+var_108] .text:000007FEEEE0FFBD call cs:??1QString@@QEAA@XZ ; QString::~QString(void) .text:000007FEEEE0FFC3 .text:000007FEEEE0FFC3 loc_7FEEEE0FFC3: ; CODE XREF: j_checkActivationCode+A2↑j .text:000007FEEEE0FFC3 test bl, bl .text:000007FEEEE0FFC5 setz bl .text:000007FEEEE0FFC8 .text:000007FEEEE0FFC8 loc_7FEEEE0FFC8: ; DATA XREF: .rdata:000007FEEEE2B828↓o .text:000007FEEEE0FFC8 lea rcx, [rsp+130h+activationCode] .text:000007FEEEE0FFCD call cs:??1QString@@QEAA@XZ ; QString::~QString(void) .text:000007FEEEE0FFD3 test bl, bl .text:000007FEEEE0FFD5 jnz loc_7FEEEE10241 .text:000007FEEEE0FFDB mov edx, 0Fh .text:000007FEEEE0FFE0 lea rcx, aActivationCode ; "activation_code" .text:000007FEEEE0FFE7 call cs:?fromAscii_helper@QString@@CAPEAU?$QTypedArrayData@G@@PEBDH@Z ; QString::fromAscii_helper(char const *,int) .text:000007FEEEE0FFED mov [rsp+130h+activationCode], rax .text:000007FEEEE0FFF2 .text:000007FEEEE0FFF2 loc_7FEEEE0FFF2: ; DATA XREF: .rdata:000007FEEEE2B830↓o .text:000007FEEEE0FFF2 lea r8, [rsp+130h+activationCode] .text:000007FEEEE0FFF7 lea rdx, [rbp+57h+var_98] .text:000007FEEEE0FFFB lea rcx, [rsp+130h+var_F0] .text:000007FEEEE10000 call cs:??AQJsonObject@@QEAA?AVQJsonValueRef@@AEBVQString@@@Z ; QJsonObject::operator[](QString const &) .text:000007FEEEE10006 mov rcx, rax .text:000007FEEEE10009 lea rdx, [rbp+57h+var_D0] .text:000007FEEEE1000D call cs:?toString@QJsonValueRef@@QEBA?AVQString@@XZ ; QJsonValueRef::toString(void) .text:000007FEEEE10013 nop .text:000007FEEEE10014 .text:000007FEEEE10014 loc_7FEEEE10014: ; DATA XREF: .rdata:000007FEEEE2B838↓o .text:000007FEEEE10014 lea rcx, [rsp+130h+activationCode] .text:000007FEEEE10019 call cs:??1QString@@QEAA@XZ ; QString::~QString(void) .text:000007FEEEE1001F mov edx, 4 .text:000007FEEEE10024 lea rcx, aDate ; "date" .text:000007FEEEE1002B call cs:?fromAscii_helper@QString@@CAPEAU?$QTypedArrayData@G@@PEBDH@Z ; QString::fromAscii_helper(char const *,int) .text:000007FEEEE10031 mov [rsp+130h+var_108], rax .text:000007FEEEE10036 .text:000007FEEEE10036 loc_7FEEEE10036: ; DATA XREF: .rdata:000007FEEEE2B840↓o .text:000007FEEEE10036 lea r8, [rsp+130h+var_108] .text:000007FEEEE1003B lea rdx, [rbp+57h+var_68] .text:000007FEEEE1003F lea rcx, [rsp+130h+var_F0] .text:000007FEEEE10044 call cs:??AQJsonObject@@QEAA?AVQJsonValueRef@@AEBVQString@@@Z ; QJsonObject::operator[](QString const &) .text:000007FEEEE1004A mov rcx, rax .text:000007FEEEE1004D lea rdx, [rbp+57h+var_B8] .text:000007FEEEE10051 call cs:?toString@QJsonValueRef@@QEBA?AVQString@@XZ ; QJsonValueRef::toString(void) .text:000007FEEEE10057 nop .text:000007FEEEE10058 .text:000007FEEEE10058 loc_7FEEEE10058: ; DATA XREF: .rdata:000007FEEEE2B848↓o .text:000007FEEEE10058 lea rcx, [rsp+130h+var_108] .text:000007FEEEE1005D call cs:??1QString@@QEAA@XZ ; QString::~QString(void) .text:000007FEEEE10063 mov edx, 7 .text:000007FEEEE10068 lea rcx, aKeyhash ; "keyHash" .text:000007FEEEE1006F call cs:?fromAscii_helper@QString@@CAPEAU?$QTypedArrayData@G@@PEBDH@Z ; QString::fromAscii_helper(char const *,int) .text:000007FEEEE10075 mov [rbp+57h+var_C8], rax .text:000007FEEEE10079 .text:000007FEEEE10079 loc_7FEEEE10079: ; DATA XREF: .rdata:000007FEEEE2B850↓o .text:000007FEEEE10079 lea r8, [rbp+57h+var_C8] .text:000007FEEEE1007D lea rdx, [rbp+57h+var_88] .text:000007FEEEE10081 lea rcx, [rsp+130h+var_F0] .text:000007FEEEE10086 call cs:??AQJsonObject@@QEAA?AVQJsonValueRef@@AEBVQString@@@Z ; QJsonObject::operator[](QString const &) .text:000007FEEEE1008C mov rcx, rax .text:000007FEEEE1008F lea rdx, [rbp+57h+var_C0] .text:000007FEEEE10093 call cs:?toString@QJsonValueRef@@QEBA?AVQString@@XZ ; QJsonValueRef::toString(void) .text:000007FEEEE10099 nop .text:000007FEEEE1009A .text:000007FEEEE1009A loc_7FEEEE1009A: ; DATA XREF: .rdata:000007FEEEE2B858↓o .text:000007FEEEE1009A lea rcx, [rbp+57h+var_C8] .text:000007FEEEE1009E call cs:??1QString@@QEAA@XZ ; QString::~QString(void) .text:000007FEEEE100A4 mov edx, 8 .text:000007FEEEE100A9 lea rcx, aCodehash ; "codeHash" .text:000007FEEEE100B0 call cs:?fromAscii_helper@QString@@CAPEAU?$QTypedArrayData@G@@PEBDH@Z ; QString::fromAscii_helper(char const *,int) .text:000007FEEEE100B6 mov [rsp+130h+var_F8], rax .text:000007FEEEE100BB .text:000007FEEEE100BB loc_7FEEEE100BB: ; DATA XREF: .rdata:000007FEEEE2B860↓o .text:000007FEEEE100BB lea r8, [rsp+130h+var_F8] .text:000007FEEEE100C0 lea rdx, [rbp+57h+var_78] .text:000007FEEEE100C4 lea rcx, [rsp+130h+var_F0] .text:000007FEEEE100C9 call cs:??AQJsonObject@@QEAA?AVQJsonValueRef@@AEBVQString@@@Z ; QJsonObject::operator[](QString const &) .text:000007FEEEE100CF mov rcx, rax .text:000007FEEEE100D2 lea rdx, [rbp+57h+var_A8] .text:000007FEEEE100D6 call cs:?toString@QJsonValueRef@@QEBA?AVQString@@XZ ; QJsonValueRef::toString(void) .text:000007FEEEE100DC nop .text:000007FEEEE100DD .text:000007FEEEE100DD loc_7FEEEE100DD: ; DATA XREF: .rdata:000007FEEEE2B868↓o .text:000007FEEEE100DD lea rcx, [rsp+130h+var_F8] .text:000007FEEEE100E2 call cs:??1QString@@QEAA@XZ ; QString::~QString(void) .text:000007FEEEE100E8 mov edx, 5 .text:000007FEEEE100ED lea rcx, aError ; "error" .text:000007FEEEE100F4 call cs:?fromAscii_helper@QString@@CAPEAU?$QTypedArrayData@G@@PEBDH@Z ; QString::fromAscii_helper(char const *,int) .text:000007FEEEE100FA mov [rsp+130h+var_110], rax .text:000007FEEEE100FF .text:000007FEEEE100FF loc_7FEEEE100FF: ; DATA XREF: .rdata:000007FEEEE2B870↓o .text:000007FEEEE100FF lea r8, [rsp+130h+var_110] .text:000007FEEEE10104 lea rdx, [rsp+130h+var_E0] .text:000007FEEEE10109 lea rcx, [rsp+130h+var_F0] .text:000007FEEEE1010E call cs:??AQJsonObject@@QEAA?AVQJsonValueRef@@AEBVQString@@@Z ; QJsonObject::operator[](QString const &) .text:000007FEEEE10114 lea rdx, [rbp+57h+var_58] .text:000007FEEEE10118 mov rcx, rax .text:000007FEEEE1011B call cs:?toValue@QJsonValueRef@@AEBA?AVQJsonValue@@XZ ; QJsonValueRef::toValue(void) .text:000007FEEEE10121 nop .text:000007FEEEE10122 .text:000007FEEEE10122 loc_7FEEEE10122: ; DATA XREF: .rdata:000007FEEEE2B878↓o .text:000007FEEEE10122 xor edx, edx .text:000007FEEEE10124 mov rcx, rax .text:000007FEEEE10127 call cs:?toInt@QJsonValue@@QEBAHH@Z ; QJsonValue::toInt(int)
и снова подставляем результат в форму activation codeCode:if __name__=="__main__": activation_code={'activation_code':'activation_code1', 'date':'', 'keyHash':'keyHash1', 'codeHash':'codeHash1', 'error':0} activation_code=encodeRSA(priv,activation_code) print activation_code
тут еще код в котором проверяются параметры jsonCode:WyJZazZaVld6VVdxSkZRTkRVMUxIUUxsVllJZVA3MnZpaWJVUmV1UGlWcitRMnJxdWtYc3MzQ3pMQncrSUFORmtOWkFhZGN0OVJEdGdNanVUT2ZtNWpMQ2tYZDBrRi95QUFJdDZhV2Nobk1iVjlJcGdRZWxoSHhvUE9QMmlBcCtRRmxRS1NTZkFaWDByRmxiclhGWGdDazB4N0tGdWRtTTVEeDBVWXljNjFPRm5ncDZiM0ZRWTBCQndBT0tXRVd6Unp4UVJjZWdvN1pOVWozd3JDOCt4ajRJZU9oaERGUy95alUzTFBPZXRMZktNNmdYUkFuOGV4bk0yQlhuazlXK0l1RTlLWnZzT2o4U1V6eDdwc2xmTmc4bEtzR0VBcHk4QVRaSThMMTdUR010YTRKdFBMOFpONjArNmpXQ2dibFphMFZVcGJWcTVBc2ZzOEFlZ2ZGTTNJcGc9PSJd
проверяется формат серийного номера
маска
сериный номер должен быть в формате
123456-123456-123456-123456
проходим и эту проверку
форматируются данные серийника и разбиваются на две части
12345612 3456123456123456
а тут еще и шифруются четырьмя различными константами
проверяется серийный номер
общий алгоритм будет таким
version = ['8e957302','c8e84503','5abfebbb','49d5b5dd']
1. 123456-123456-123456-123456
2. 123456123456123456123456
3. 12345612 3456123456123456
4. des_ecb_encode('8e957302','12345612')=='3456123456 123456'
можем написать генератор для серийного номера
получим такоеCode:def get_serial(key,pref): pref=pref[:8] d=DES.new(key) e=d.encrypt(pref[:8]) a=e.encode('hex').upper() sn=pref[:6]+'-'+pref[6:]+a[:4]+"-"+a[4:4+6]+'-'+a[4+6:] return sn if __name__=="__main__": codes=['8e957302','c8e84503','5abfebbb','49d5b5dd'] code='49d5b5dd' serial=get_serial(code,'12345678') print serial
как результат прошли еще одну проверкуCode:123456-78A8E7-04D461-0D7679
на этот раз у меня все, на следующем уроке мы сформируем правильный activation code

















Reply With Quote
Thanks