Skip to content

Instantly share code, notes, and snippets.

View toptensoftware's full-sized avatar

Brad Robinson toptensoftware

View GitHub Profile
@toptensoftware
toptensoftware / ModuleBase.cs
Created October 11, 2016 00:56
ModuleBase class
public abstract class ModuleBase
{
public abstract string GetModuleName();
public abstract string GetModuleFileName();
public abstract void Load(Machine machine);
public abstract void Unload(Machine machine);
public abstract IEnumerable<string> GetReferencedModules();
public abstract void Link(Machine machine);
public abstract void Init(Machine machine);
public abstract void Uninit(Machine machine);
@toptensoftware
toptensoftware / ResolveReferencedModules.cs
Created October 11, 2016 01:01
Resolving Referenced Modules
// Recursively call self (ModuleManager) to load each referenced module
foreach (var m in nativeModule.GetReferencedModules())
{
LoadModule(m);
}
// elsewhere...
// Module16 implements GetReferencedModules by reading the list from the NE file reader
class Module16 : ModuleBase
public override void Load(Machine machine)
{
// Load all segments
for (int i=0; i<_neFile.Segments.Length; i++)
{
// Get the segment
var seg = _neFile.Segments[i];
// Work out how much memory needed. For the automatic data segments
// add the size of the heap and for programs add on the stack size
@toptensoftware
toptensoftware / ApplyRelocations.cs
Created October 11, 2016 01:19
Applying Relocations
public override void Link(Machine machine)
{
for (int i = 0; i < _neFile.Segments.Count; i++)
{
// Get the segment
var seg = segments[i];
// Get access to the byte array backing it
var data = machine.GlobalHeap.GetBuffer(seg.globalHandle);
@toptensoftware
toptensoftware / ExampleRelocations.cs
Last active October 11, 2016 04:04
Example relocations
// InternalReference links to another segment in this module
if (reloc.type == RelocationType.InternalReference)
{
var targetSegment = segments[reloc.param1 - 1];
ApplyRelocations(data, reloc.offset, (uint)(targetSegment.globalHandle << 16 | reloc.param2), additive);
}
// ImportedOrdinal links to an entry point in another module
if (reloc.type == RelocationType.ImportedOrdinal)
{
@toptensoftware
toptensoftware / ApplyRelocation.cs
Created October 11, 2016 01:31
Applying a chain of relocations
void ApplyRelocations(byte[] data, ushort offset, uint value, bool additive)
{
if (additive)
{
data.WriteDWord(offset, (uint)(data.ReadDWord(offset) + value));
}
else
{
while (offset != 0xFFFF)
{
@toptensoftware
toptensoftware / PatchExportedFunctions.cs
Last active October 11, 2016 02:24
Patching exported functions
foreach (var ep in _neFile.GetAllEntryPoints().Where(x=>(x.flags & Win3muCore.NeFile.EntryPoint.FLAG_EXPORTED)!=0))
{
// Get the segment
var segment = segments[ep.segmentNumber - 1].globalHandle;
var data = machine.GlobalHeap.GetBuffer(segment);
// Shared DS?
if ((ep.flags & Win3muCore.NeFile.EntryPoint.FLAG_SHAREDDS)!=0)
{
// Insert MOV AX,xxxx instruction
public override void Init(Machine machine)
{
if (IsDll)
{
// Save DS
var saveds = machine.ds;
// Call Library entry point
machine.di = hModule;
machine.ds = DataSegment == null ? (ushort)0 : DataSegment.globalHandle;
@toptensoftware
toptensoftware / GetProcAddress16.cs
Created October 11, 2016 02:41
Getting the address of a 16-bit function
// Module16's GetProcAddress passes through to NeFileReader.GetProcAddress...
public uint GetProcAddress(ushort ordinal)
{
// Look up the entry point
EntryPoint ep;
if (!_entryPoints.TryGetValue(ordinal, out ep))
return 0;
// Constant?
if (ep.segmentNumber == 0xFE)
@toptensoftware
toptensoftware / FakeUserDll.cs
Last active October 11, 2016 05:14
Fake demonstration of calling Windows API from 16-bit code
public class FakeUserDll : ModuleBase
{
public FakeUserDll()
{
}
// A reference back to the machine
Machine _machine;
// Address of the 16-bit MessageBox thunk