开发者

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;
    for (int i = 0 ; i< buffer.size() ;i++)
        sum += buffer[i];
    srand(sum);
    uint8_t hash[0x10];
    for (int i = 0; i < 0x10; i++)
    hash[i] =(uint8_t)rand();
    for (int i = 1; i < 0x100; i++)
        {
            key[i * 2] = (uint8_t)i;
            key[(i * 2) + 1] = (uint8_t)(i ^ hash[i & 0x0F]);
        }
    for (int i = 1; i < 0x100; i++)
    for (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, 0x6开发者_JAVA百科B, 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());
    for (int i = 0; i < 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);
    for (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;
        for (uint8_t i = 0; i <= 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) {
    for (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 a breakpoint in testcrypto.exe.

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.

This may also be due to the user pressing F12 while testcrypto.exe has focus.


You have a classic buffer overrun. Here you allocate 200 bytes for key:

this->key = new uint8_t[200];

Here, however:

for (int i = 1; i < 0x100; i++)
    {
        key[i * 2] = (uint8_t)i;

You (attempt to) write to k[2] through key[2 * 0x100]. 2 * 0x100 is 0x200, which is 512 in decimal. It would appear that where you allocate the buffer, you should really allocate 0x200 elements.

Some of the other code looks like it tries to access key[0x200] -- to make that work, you'd want/need to allocate 0x201 elements (0x200 elements will run from key[0] through key[0x1ff] inclusive).

Edit: doing a bit more looking, it gets even worse. Perhaps putting these three lines next to each other will make the 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 a reference to a local variable, so the caller receives a dangling reference.


j < 0x100;

0x100 is not the same as 100. It's 256. And your key array is only 200 elements long.

You then go off and try to access key[j * 2], which is way off the end of the array, trampling all over random bits of memory. That's your problem.

Your other problem is using xor-swapping instead of something more readable - while you might think it's a "neat trick", it really isn't. It makes things much less legible and doesn't provide any meaningful performance benefit.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜