c++ - This may be due to a corruption of the heap, which indicates a bug in testcrypto.exe or any of the DLLs it has loaded -
#pragma once #include <string> #include <vector> #include <stdint.h> class passwordcrypt { public: passwordcrypt(std::vector<uint8_t> buffer); ~passwordcrypt(void); void passcrypto(std::vector<uint8_t> buffer); const std::vector<uint8_t>& encrypt(const std::vector<uint8_t>& buffer); const std::vector<uint8_t>& decrypt(std::vector<uint8_t>& buffer); private: uint8_t* key; }; -------------------------------------------------------------------------------------- #include "passwordcrypt.h" passwordcrypt::passwordcrypt(std::vector<uint8_t> buffer) { this->key = new uint8_t[200]; int sum = 0; (int = 0 ; i< buffer.size() ;i++) sum += buffer[i]; srand(sum); uint8_t hash[0x10]; (int = 0; < 0x10; i++) hash[i] =(uint8_t)rand(); (int = 1; < 0x100; i++) { key[i * 2] = (uint8_t)i; key[(i * 2) + 1] = (uint8_t)(i ^ hash[i & 0x0f]); } (int = 1; < 0x100; i++) (int j = 1 + i; j < 0x100; j++) if (key[(i * 2) + 1] < key[(j * 2) + 1]) { key[i * 2] ^= key[j * 2]; key[j * 2] ^= key[i * 2]; key[i * 2] ^= key[j * 2]; key[(i * 2) + 1] ^= key[(j * 2) + 1]; key[(j * 2) + 1] ^= key[(i * 2) + 1]; key[(i * 2) + 1] ^= key[(j * 2) + 1]; } } passwordcrypt::~passwordcrypt(void) { delete[] this->key; } const uint8_t scancodetovirtualkeymap[] = { 0x00, 0x1b, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0xbd, 0xbb, 0x08, 0x09, 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4f, 0x50, 0xdb, 0xdd, 0x0d, 0x11, 0x41, 0x53, 0x44, 0x46, 0x47, 0x48, 0x4a, 0x4b, 0x4c, 0xba, 0xc0, 0xdf, 0x10, 0xde, 0x5a, 0x58, 0x43, 0x56, 0x42, 0x4e, 0x4d, 0xbc, 0xbe, 0xbf, 0x10, 0x6a, 0x12, 0x20, 0x14, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x90, 0x91, 0x24, 0x26, 0x21, 0x6d, 0x25, 0x0c, 0x27, 0x6b, 0x23, 0x28, 0x22, 0x2d, 0x2e, 0x2c, 0x00, 0xdc, 0x7a, 0x7b, 0x0c, 0xee, 0xf1, 0xea, 0xf9, 0xf5, 0xf3, 0x00, 0x00, 0xfb, 0x2f, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0xed, 0x00, 0xe9, 0x00, 0xc1, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x09, 0x00, 0xc2, 0x00, }; const uint8_t virtualkeytoscancodemap[] = { 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x0f, 0x00, 0x00, 0x4c, 0x1c, 0x00, 0x00, 0x2a, 0x1d, 0x38, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x39, 0x49, 0x51, 0x4f, 0x47, 0x4b, 0x48, 0x4d, 0x50, 0x00, 0x00, 0x00, 0x54, 0x52, 0x53, 0x63, 0x0b, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x2e, 0x20, 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26, 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1f, 0x14, 0x16, 0x2f, 0x11, 0x2d, 0x15, 0x2c, 0x5b, 0x5c, 0x5d, 0x00, 0x5f, 0x52, 0x4f, 0x50, 0x51, 0x4b, 0x4c, 0x4d, 0x47, 0x48, 0x49, 0x37, 0x4e, 0x00, 0x4a, 0x53, 0x35, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x57, 0x58, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x36, 0x1d, 0x1d, 0x38, 0x38, 0x6a, 0x69, 0x67, 0x68, 0x65, 0x66, 0x32, 0x20, 0x2e, 0x30, 0x19, 0x10, 0x24, 0x22, 0x6c, 0x6d, 0x6b, 0x21, 0x00, 0x00, 0x27, 0x0d, 0x33, 0x0c, 0x34, 0x35, 0x28, 0x73, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x56, 0x1b, 0x2b, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x5c, 0x7b, 0x00, 0x6f, 0x5a, 0x00, 0x00, 0x5b, 0x00, 0x5f, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00 }; const std::vector<uint8_t>& passwordcrypt::encrypt(const std::vector<uint8_t>& buffer) { std::vector<uint8_t> result(buffer.size()); (int = 0; < buffer.size(); i++) { bool upper = false; if (buffer[i] == 0) break; else { uint8_t b =this->key[buffer[i] * 2]; if (b > 0x80) { b = (uint8_t)(this->key[buffer[i] * 2] - 0x80); upper = true; } result[i] += scancodetovirtualkeymap[b]; } if (!upper && result[i] >= 'a' && result[i] <= 'z') result[i] += 'a' - 'a'; } return result; } const std::vector<uint8_t>& passwordcrypt::decrypt(std::vector<uint8_t>& buffer) { std::vector<uint8_t> result(buffer.size(), 0); (int j = 0; j < buffer.size(); j++) { uint8_t c = buffer[j]; if (buffer[j] >= 'a' && buffer[j] <= 'z') buffer[j] -= 'a' - 'a'; uint8_t d = virtualkeytoscancodemap[buffer[j]]; if (c >= 'a' && c <= 'z') d += 0x80; (uint8_t = 0; <= 255; i++) { uint8_t b = (uint8_t)this->key[i * 2]; if (b == d) { result[j] = i; break; } } } return result; } --------------------------------------------------------------------------------------- #include <iostream> #include <windows.h> #include <string> #include <stdint.h> #include "passwordcrypt.h" #include <iomanip> using namespace std; void output_hex(std::ostream& out, std::vector<uint8_t>& data) { (std::vector<uint8_t>::iterator i=data.begin();i<data.end();i++) out << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(data[*i]) << " "; out << endl; } int main() { std::string test="hellow world!"; std::vector<uint8_t> buf(test.begin(), test.end()); passwordcrypt dec(buf); //output_hex(cout, buf); std::vector<uint8_t> enced = dec.encrypt(buf); //output_hex(cout, enced); std::vector<uint8_t> deced = dec.decrypt(enced); //output_hex(cout, deced); system("pause"); return 0; }
error:
windows has triggered breakpoint in testcrypto.exe.
this may due corruption of heap, indicates bug in testcrypto.exe or of dlls has loaded.
this may due user pressing f12 while testcrypto.exe has focus.
you have classic buffer overrun. here allocate 200 bytes key
:
this->key = new uint8_t[200];
here, however:
for (int = 1; < 0x100; i++) { key[i * 2] = (uint8_t)i;
you (attempt to) write k[2]
through key[2 * 0x100]
. 2 * 0x100 0x200, 512 in decimal. appear allocate buffer, should allocate 0x200
elements.
some of other code looks tries access key[0x200]
-- make work, you'd want/need allocate 0x201 elements (0x200 elements run key[0] through key[0x1ff] inclusive).
edit: doing bit more looking, gets worse. perhaps putting these 3 lines next each other make next problem more obvious:
const std::vector<uint8_t>& passwordcrypt::encrypt(const std::vector<uint8_t>& buffer) { std::vector<uint8_t> result(buffer.size()); [ ...] return result;
you're returning reference local variable, caller receives dangling reference.
Comments
Post a Comment