Hãy phá vỡ nó xuống thì chúng tôi, một bước tại một thời điểm.
void CryptoBuffer(unsigned char *Buffer, unsigned short length)
{
unsigned short i;
for(i=0; i < length; i++)
{
*Buffer ^= 0xAA;
*Buffer++ += 0xC9;
}
}
Bất kể một số nhận xét khác, đây là cách bạn thường làm những việc này trong C/C++. Không có gì lạ mắt về mã này, và nó không quá phức tạp, nhưng tôi nghĩ tốt nhất là chia nhỏ nó ra để cho bạn thấy điều gì xảy ra.
Những điều cần lưu ý:
- unsigned char là cơ bản giống như byte trong C#
- dài unsigned có giá trị từ 0-65.536. Int nên làm các trick.
- Bộ đệm có tăng sau
- Việc gán byte (+ = 0xC9) sẽ tràn. Nếu nó tràn nó cắt ngắn đến 8 bit trong trường hợp này.
- Bộ đệm được chuyển bởi ptr, vì vậy con trỏ trong phương thức gọi sẽ giữ nguyên.
- Đây chỉ là mã C cơ bản, không có C++. Nó là khá an toàn để giả định mọi người không sử dụng quá tải nhà điều hành ở đây.
Điều "khó" duy nhất ở đây là bộ đệm ++. Chi tiết có thể được đọc trong cuốn sách "Exceptional C++" từ Sutter, nhưng một ví dụ nhỏ giải thích điều này là tốt. Và may mắn thay, chúng tôi có một ví dụ hoàn hảo theo ý của chúng tôi. Một đen dịch của mã trên là:
void CryptoBuffer(unsigned char *Buffer, unsigned short length)
{
unsigned short i;
for(i=0; i < length; i++)
{
*Buffer ^= 0xAA;
unsigned char *tmp = Buffer;
*tmp += 0xC9;
Buffer = tmp + 1;
}
}
Trong trường hợp này biến temp có thể được giải quyết trivially, dẫn chúng tôi:
void CryptoBuffer(unsigned char *Buffer, unsigned short length)
{
unsigned short i;
for(i=0; i < length; i++)
{
*Buffer ^= 0xAA;
*Buffer += 0xC9;
++Buffer;
}
}
Thay đổi mã này vào C# tại là khá dễ dàng :
private void CryptoBuffer(byte[] Buffer, int length)
{
for (int i=0; i<length; ++i)
{
Buffer[i] = (byte)((Buffer[i]^0xAA) + 0xC9);
}
}
Điều này về cơ bản giống như mã được chuyển của bạn. Điều này có nghĩa là một nơi nào đó trên đường đi một cái gì đó khác đã đi sai ... Vì vậy, hãy hack cryptobuffer phải không? :-)
Nếu chúng ta giả định rằng byte đầu tiên không được sử dụng (như bạn nói) và rằng '0xAA' và/hoặc '0xC9' là sai, chúng ta chỉ có thể thử tất cả các kết hợp:
static void Main(string[] args)
{
byte[] orig = new byte[] { 0x03, 0x18, 0x01 };
byte[] target = new byte[] { 0x6F, 0x93, 0x8b };
for (int i = 0; i < 256; ++i)
{
for (int j = 0; j < 256; ++j)
{
bool okay = true;
for (int k = 0; okay && k < 3; ++k)
{
byte tmp = (byte)((orig[k]^i) + j);
if (tmp != target[k]) { okay = false; break; }
}
if (okay)
{
Console.WriteLine("Solution for i={0} and j={1}", i, j);
}
}
}
Console.ReadLine();
}
Hiện tại, chúng tôi đi: oops không có giải pháp nào. Điều đó có nghĩa rằng các cryptobuffer không làm những gì bạn nghĩ rằng nó đang làm, hoặc một phần của mã C là mất tích ở đây. F.ex. họ có thực sự chuyển 'Buffer' sang phương thức CryptoBuffer hay họ đã thay đổi con trỏ trước đây?
Kết luận, tôi nghĩ câu trả lời duy nhất ở đây là thông tin quan trọng để giải quyết câu hỏi này bị thiếu.
Đó là một số mã C nghiêm trọng khó đọc. Ai nghĩ rằng nó là một ý tưởng tốt để trộn dereferencing, incrementing, bổ sung và phân công trong một biểu thức? –
Với đầu vào ví dụ của bạn, tôi nhận được câu trả lời tương tự cho C và C#, ngoại trừ byte đầu tiên (vì bạn không đưa ra dấu hiệu nào trong mã là tại sao nó bị bỏ qua). – user7116
@Eric: Kernighan và Ritchie dường như thích loại mã đó, nếu bộ nhớ của tôi đọc Ngôn ngữ lập trình C trong thập niên 80 phục vụ ...;) Ví dụ về strcpy của họ trông giống như trong khi ((* s ++) = * t ++)! = '\ 0'); '... Shudder –