请CTFE高人指教编译时汇编器
oldrev
2007-04-04
我写了一个简单的堆栈式虚拟机用来加密一个程序的序列号算法,其中的 enum Instruction 的定义可以在编译时由 Ruby 脚本产生随机的操作码,大大增加破解难度。
我正在努力创建一个编译时汇编器,用于汇编这些代码,可是编译时的字符串处理功能很弱,如果谁有这方面的经验,欢迎赐教。 module vm; import std.stdio; class Stack { private uint[1024] m_data; private const uint m_bottom = m_data.length; private uint m_top; this() { clear(); } public void clear() { m_top = m_bottom; } public void push(uint n) { m_top--; m_data[m_top] = n; } public uint count() { return m_bottom - m_top; } public uint pop() { return m_data[m_top++]; } public uint top() { assert(m_top < m_bottom); return m_data[m_top]; } } enum Instruction : ushort { Add = 1, Sub, Mul, Div, Push, Pop, Load, Store, Jump, JE, JLE, JG, JGE, And, Not, Or, Xor, End } static Instruction getOp(uint Len)(char[Len] str) { Instruction ins; for(uint i = 0; i < str.length; i++) { if(str[i] == ' ') { switch(str[0 .. i]) { case "add": ins = Instruction.Add; break; case "sub": ins = Instruction.Sub; break; } break; } } return Instruction; } class VirtualMachine { private Stack m_stack; ubyte[] m_memory; uint m_pc = 0; uint m_progPtr = 0; bool m_flag; this(uint memSize = 1024) { m_memory.length = memSize; m_stack = new Stack; reset(); } public void reset() { m_stack.clear(); m_pc = 0; m_progPtr = 0; } void vasm(Instruction ins, uint oprand) { Instruction* iptr = cast(Instruction*)(m_memory.ptr + m_progPtr); vasm(ins); uint* ptr = cast(uint*)(m_memory.ptr + m_progPtr) ; *ptr = oprand; m_progPtr += uint.sizeof; } void vasm(Instruction ins) { Instruction* iptr = cast(Instruction*)(m_memory.ptr + m_progPtr); *iptr = ins; m_progPtr += Instruction.sizeof; } bool doInstruction() { Instruction* iptr = cast(Instruction*)(m_memory.ptr + m_pc); writefln("m_pc=%d Ins=%d ",m_pc, *iptr); m_pc += Instruction.sizeof; uint* oprand = cast(uint*)(m_memory.ptr + m_pc); switch(*iptr) { case Instruction.Add: uint x = m_stack.pop; uint y = m_stack.pop; m_stack.push(x + y); break; case Instruction.Sub: uint x = m_stack.pop; uint y = m_stack.pop; m_stack.push(x - y); break; case Instruction.Mul: uint x = m_stack.pop; uint y = m_stack.pop; m_stack.push(x * y); break; case Instruction.Div: uint x = m_stack.pop; uint y = m_stack.pop; m_stack.push(x / y); break; case Instruction.Pop: m_stack.pop; break; case Instruction.Push: m_stack.push(*oprand);//get oprand); m_pc += uint.sizeof; break; case Instruction.Load: m_stack.push(m_memory[*oprand]);//get oprand); m_pc += uint.sizeof; break; case Instruction.Store: uint x = m_stack.pop(); m_memory[*oprand] = x; m_pc += uint.sizeof; break; case Instruction.Jump: m_pc = *oprand;// get oprand break; case Instruction.JE: uint x = m_stack.pop; uint y = m_stack.pop; if(x == y)m_pc = *oprand; else m_pc += uint.sizeof; break; case Instruction.JLE: // top <= bottom uint x = m_stack.pop; uint y = m_stack.pop; if(x <= y)m_pc = *oprand; else m_pc += uint.sizeof; break; case Instruction.JG: // top > bottom uint x = m_stack.pop; uint y = m_stack.pop; if(x > y)m_pc = *oprand; else m_pc += uint.sizeof; break; case Instruction.JGE: uint x = m_stack.pop; uint y = m_stack.pop; if(x >= y)m_pc = *oprand; else m_pc += uint.sizeof; break; case Instruction.And: uint x = m_stack.pop; uint y = m_stack.pop; m_stack.push(x & y); break; case Instruction.Or: uint x = m_stack.pop; uint y = m_stack.pop; m_stack.push(x | y); break; case Instruction.Not: uint x = m_stack.pop; m_stack.push(!x); break; case Instruction.Xor: uint x = m_stack.pop; uint y = m_stack.pop; m_stack.push(x ^ y); case Instruction.End: return true; //normal terminated break; default: throw new Exception("Invalid instruction"); break; } return false; } uint top() { return m_stack.top; } uint run() { reset; while(!doInstruction()){} return top; } } void main() { auto s = new Stack; s.push(1); writefln(s.top); s.push(2); s.push(3); writefln(s.pop); writefln(s.pop); writefln(s.pop); // 计算 (12+2)*3 auto vm = new VirtualMachine(); vm.vasm(Instruction.Push, 12); vm.vasm(Instruction.Push, 2); vm.vasm(Instruction.Add); vm.vasm(Instruction.Push, 3); vm.vasm(Instruction.Mul); vm.vasm(Instruction.End); vm.run; writefln("Result=", vm.top); } |
|
qiezi
2007-04-17
随机?编译时可供随机的东西不多,可以取时间,用__TIMESTAMP__和__FILE__再加上__LINE__生成吧。编译时字符串功能比较弱,不过还是可以做不少事的。
|
|
oldrev
2007-04-17
操作码是由Ruby脚本随机产生的
|
|
qiezi
2007-04-17
这个东西随机生成一下:
# enum Instruction : ushort # { # Add = 1000, # Sub = 3212341, # Mul = 12345346, # Div = 324554, # Push = 23452377, # Pop = 9045635, # Load, # Store, # Jump, # JE, # JLE, # JG, # JGE, # And, # Not, # Or, # Xor, # End # } |
|
oldrev
2007-04-17
就是这个了
|
|
qiezi
2007-04-17
把这一段用ruby生成,在D里面import+mixin弄进去就行咯。。
|
|
oldrev
2007-04-17
我就是这个意思,只是还没完成
|
相关讨论
相关资源推荐
- i18n-google-sheets-importer:从Google Docs电子表格自动生成JSON转换文件
- blacken-docs:在文档文件中的python代码块上运行“ black”
- google-docs-equation-shortcuts:Google Docs公式编辑器快捷方式的非官方文档
- library:由Google Docs提供支持的协作文档网站
- csv2github:从 Google Docs(CSV 文件)电子表格转换为 Github 问题
- docs-soap:用于清除google docs生成的剪贴板内容的库
- GoogleDocsCMS:使用 Google Docs 电子表格进行内容管理的单页 AngularJS 网站
- google-docs-api:与谷歌文档混乱
- 注册GitHub时出现Unable to verify your captcha response.Please visit https://docs.github.com/articles/解决方案
- boopie-docs:查看正在运行的网站!