C代码索引计算解析及C#复现key4解密逻辑的技术问询
Let's break down that tricky pointer arithmetic in your C code and figure out how to replicate it cleanly in C#.
First: How Pointer Arithmetic Works in C
In C, array indexing is just syntactic sugar for pointer operations. When you write inputData[i], it’s exactly equivalent to *(inputData + i) — regardless of whether i is positive or negative. The compiler only cares if the resulting memory address is valid (which it is here, since it points to stack memory your program owns).
Decoding decoder - (char*)data
The expression decoder - (char*)data calculates the byte offset between the start of the decoder array and the start of the data array. Since decoder is a local stack variable and data is a function parameter, decoder lives at a lower memory address than data — hence the negative offset you saw (like -300 or -436). This offset is fixed for the duration of the function call, since both arrays’ memory positions don’t change.
Simplifying inputData[decoder - (char*)data]
Let’s substitute what we know to demystify this line:
inputDatastarts as(char*)data, and increments by 1 each loop iteration. Aftercountersteps, it’s equivalent to(char*)data + counter.- Let
fixedOffset = decoder - (char*)data(the negative value you measured, e.g.,-300).
So:
inputData[fixedOffset] = *(inputData + fixedOffset) = *( (char*)data + counter + fixedOffset )
But since fixedOffset = decoder - (char*)data, we can substitute that in:
*( (char*)data + counter + (decoder - (char*)data) ) = *( decoder + counter )
Which is exactly decoder[counter]!
The negative index is just a roundabout way to access the counter-th element of the decoder array. The C compiler doesn’t bat an eye at negative indexes here — it just computes the memory address and reads from it.
Replicating This in C#
Now that we’ve simplified the logic, you can ditch the confusing negative indexes and replicate the behavior directly:
First, replicate the
decoderarray exactly as in the C code:// Match your original C decoderKey values char[] decoderKey = { -20, 100, -50, -70, 40, /* ... rest of your values ... */ }; char[] decoder = new char[44]; // Copy first 40 elements from decoderKey (matches memcpy in C) Array.Copy(decoderKey, decoder, 40); // Set decoder[40] to decoderKey[40] (matches the explicit assignment) decoder[40] = decoderKey[40]; // Note: decoder[41], decoder[42], decoder[43] are uninitialized stack garbage in C // If your decryption relies on these values, you’ll need to capture their exact bytes from the original C program // and add them to the decoder array in C#.Then compute
key4using the simplified logic:// Assume inputData is your 128-byte array in C# for (int counter = 0; counter < cbSize; counter++) { // This is exactly equivalent to the C code's key4 calculation char key4 = inputData[counter] ^ decoder[counter]; // Apply the rest of the decryption logic as in the original code inputData[counter] = key4; if (counter % 4 == 0) inputData[counter] = (char)(key1 ^ key4); if (counter % 4 == 1) inputData[counter] ^= key3; }
Edge Case: When counter >= 44
In the original C code, decoder is only 44 elements long. When counter exceeds 43, decoder[counter] actually reads uninitialized stack memory beyond the array. If your decryption depends on these values, you’ll need to:
- Run the original C program, capture the exact bytes stored in the stack right after the
decoderarray, then extend your C#decoderarray to include those bytes. - If your
cbSizeis 44 or less, you don’t need to worry about this.
内容的提问来源于stack exchange,提问作者Malcolm McCaffery

