-
Notifications
You must be signed in to change notification settings - Fork 0
/
X86Writer.cs
110 lines (90 loc) · 3.03 KB
/
X86Writer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
* (c) 2008 The Managed.X86 Project
*
* Licensed under the terms of the New BSD License.
*
* Authors:
* Alex Lyman (<mailto:mail.alex.lyman@gmail.com>)
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace Managed.X86 {
public partial class X86Writer {
readonly Stream stream;
readonly BinaryWriter writer;
readonly IntPtr baseAddress;
public X86Writer(Stream stream, IntPtr baseAddress) {
this.stream = stream;
this.writer = new BinaryWriter(stream);
this.baseAddress = baseAddress;
}
public IntPtr Position {
get {
return new IntPtr(baseAddress.ToInt32() + stream.Position);
}
set {
stream.Seek(
value.ToInt64() - baseAddress.ToInt64(),
SeekOrigin.Begin
);
}
}
#region Utilities
private void address_byte(Byte m, Byte o, Byte r) {
this.writer.Write(
(byte)
(((m & 0x03) << 6)
| ((o & 0x07) << 3)
| (r & 0x07)
)
);
}
private void reg_emit32(X86Register32 dest, X86Register32 src) {
address_byte(3, (byte)(dest), (byte)(src));
}
private void reg_emit16(X86Register16 dest, X86Register16 src) {
address_byte(3, (byte)(dest), (byte)(src));
}
private void reg_emit8(X86Register8 dest, X86Register8 src) {
address_byte(3, (byte)(dest), (byte)(src));
}
private void imm_emit8(Int32 value) { writer.Write((Byte)value); }
private void imm_emit16(Int32 value) { writer.Write((Int16)value); }
private void imm_emit32(Int32 value) { writer.Write((Int32)value); }
internal static bool is_imm8(Int32 imm) { return (((int)(imm) >= -128 && (int)(imm) <= 127)); }
internal static bool is_imm16(Int32 imm) { return (((int)(imm) >= -(1 << 16) && (int)(imm) <= ((1 << 16) - 1))); }
#endregion
public X86Label CreateLabel() { return new X86Label(this); }
public X86Label CreateLabel(IntPtr position) { return new X86Label(this, position); }
public X86Label CreateLabel(int offset) { return new X86Label(this, new IntPtr(this.Position.ToInt32() + offset)); }
public void Nop() { writer.Write(new byte[] { 0x90 }); }
public void CpuId() { writer.Write(new byte[] { 0x0F, 0xA2 }); }
public void ClearCarryFlag() { writer.Write(new byte[] { 0xF8 }); }
public void ClearDirectionFlag() { writer.Write(new byte[] { 0xFC }); }
public void ClearInteruptFlag() { writer.Write(new byte[] { 0xFA }); }
public void ComplementCarryFlag() { writer.Write(new byte[] { 0xF5 }); }
public void ByteSwap(X86Register32 reg) {
writer.Write(
new byte[] {
0x0F,
(byte)(0xC8 | (byte)reg)
}
);
}
public void Halt() { writer.Write(new byte[] { 0xF4 }); }
public void Int(byte type) {
writer.Write(new byte[] { 0xCD });
writer.Write(type);
}
public void Return() { writer.Write(new byte[] { 0xCB }); }
public void Return(Int16 stackDisp) {
writer.Write(new byte[] { 0xCA });
writer.Write(stackDisp);
}
public void Retn() {
writer.Write(new byte[] { 0xC3 });
}
}
}