我有一个Keygen的C源代码,用于为Dell锁定的BIOS生成“主代码”。
经过数周的阅读和询问,尝试了一下,很难理解,并且得到了各种各样的结果。
但是,出于冒险和学术目的,有很多我不知道如何用C#代码编写的东西,这是我的目标。
例如,我在C上说unsigned char outData[16]
在C#中,我将其重写如下:
byte* outData = stackalloc byte[16];
这样,C#上存储的字节值在RAM上的大小与C上的无符号字符相同(基于http://bytes.com/topic/c-sharp/answers/658913-unsigned-char)
然后,我可以在C#中执行以下操作:
int* testPointer = (int*) outData;
*testPointer = 0x67452301;
通过这样做,我修改了outData的位置0、1、2和3(字节是C#上int的四分之一(8位vs 32位),与无符号char和int在C上的int关系相同没有错)。
所有上述
byte outData
和testPointer
的事情都可以通过这种方式在C上完成:unsigned char outData[16];
*(int *)(&outData[0]) = 0x67452301;
然后,再次更改outData的位置1、2、3和4(在这种情况下,索引从1开始,因为它是C,而不是C#)。
因此,从技术上讲,使用32位整数指针更改了无符号char的值,并将其移植到C#,并且从技术上讲,它必须提供与C上相同的结果。
现在,我想通过32位int指针从C#上的函数更改outData的值,但是,我不会将其作为参数。因此,只有一种解决方案,使outData成为全局变量。随之而来的是大麻烦了……如果我将outData设置为全局的,则它必须包含在类或结构中(如果它不在方法中)(只要我没有,方法上的变量就不是并且不能是全局的)知道)。
如果我通过struct / class进行全局outData操作(按照我所知的唯一方法),outData将成为托管数据类型,由于GC(GarbageCollector),它在RAM上从此处移动到那里,并且使用指向outData的指针成为更大的麻烦。因此,这是一条固定的语句,用于将临时的outData临时放在RAM上的固定位置,但也很麻烦,不允许在固定的语句上进行强制转换,然后我不能这样做:
int* testPointer = (int*) outData;
,其中outData具有除了testPointer和强制转换,还需要另一个块大小。以前所有的东西都说过,这才是真正的问题。如何通过32位int指针从C#上的函数更改outData的值?或...我可以使用哪种算法通过指针对outData进行这些更改,并假设outData将成为不需要不安全上下文的标准值类型?
真的很想为第二个问题提供更多答案,因为我要实现的真正目标是将C代码移植到C#,并使用OO(面向对象)范式。
我疯狂地试图理解一种算法,以通过指针并使用不同的块大小来更改存储在RAM上的值,并且只有一种方法可以做到这一点,并且没有指针,可以在C#和其他代码上使用OO编程语言。
期待您的任何答复!
并且,作为参考,这是我想要移植的程序的完整C代码:
http://pastebin.com/w8VQjVBu
我已经完成了大约40%的移植,那些C函数用于指针,不同的块大小,而且这些东西在%*&上确实让我痛苦了好几个星期了!
最佳答案
听起来您正在尝试将32位int的值复制到字节数组的前四个字节中。
为此,请使用BitConverter.GetBytes方法并将结果字节复制到另一个数组中:
var n = 0xFAFBFCFD;
var a = new byte[16];
var temp = BitConverter.GetBytes(n);
temp.CopyTo(a, 0);
现在:
a[0] == 0xFD
a[1] == 0xFC
a[2] == 0xFB
a[3] == 0xFA
就像一些评论说的那样,试图像编写C一样编写C#是一个坏主意。