Introduction to the SourcePoint Assembler

I bet that you didn’t know that SourcePoint has a built-in assembler! The “asm” command can assemble in-line instructions into memory. It provides an easy way to quickly patch instructions in memory, to deliver quick fixes, or for shellcode research.

In its simplest form, the assembler can display disassembled instructions in memory. For example, to display three instructions at the current execution point, use:

asm cs:rip length 3

SourcePoint disassembler

Note the difference between the two above examples. The assembler is smart enough to know the difference between the IP and the RIP (64 bits). Not bad. The SourcePoint command language, in general, will honor the “bitness” of any command entered, and is context-aware.

The assembler itself assembles instructions in-line using the current processor modes and settings and places the instruction code in memory. The current focus processor settings are used by default, but may be overridden by the command language or assembler directives. The assembler has been designed to accept all of the assembler forms output by the SourcePoint disassembler as well as the common forms found in Intel assemblers. I’m so glad that it doesn’t use the AT&T syntax! Although we did have one customer once who requested it.

One thing to keep in mind is that this is a single-pass assembler, so it can’t use labels that haven’t already been defined. So, you’re not going to write a big assembly language game using it. However, it does offer the ability to define labels, and the assembler offers the org directive for out-of-order assembly; so it’s fairly flexible for simple programs, and what it does, it does well.

One cool feature that I use is the $ symbol as a shorthand key for the current assembly address. The $ can be used alone or inside an expression (e.g., $+10). This makes it easy to enter loops. I use these to create deadloops a lot.

For example, to generate an infinite loop at the current execution point:

asm $ = "jmp $"

“Batch” entry of assembly language instructions can be issued from the command line, and individual instructions can be chained together on the command line with the use of the comma separator. For example, to patch out 10 instructions at address 700L with NOPs, use the following:

asm 700 len 10t “nop”

Chained NOP instructions

And as another example using batch mode and chaining:

asm 700 len 20t = "add bx,ax", "add cx,ax"

Assembly language chaining

The “t” suffice to the length indicates a decimal constant.

Or, alternatively, assembly language instructions can be entered interactively, one line at a time. For example, a small program that just does a loop can be entered like this:

P0>asm 700 =

P0@0000000000000700L>mov rax, 1

P0@000000000000070AL>inc rax

P0@000000000000070DL>jmp 70a

P0@000000000000070FL>endasm

And finally, assembly language programs can be entered in as a macro, to reduce the possibility of making typos in interactive mode. Here’s a macro file, named first.mac, that creates the looping program, sets the instruction pointer, and then runs itself:

asm 700 =

mov rax, 1

inc rax

jmp 70a

endasm

rip = 700

go

And then, just by loading the macro, it assembles the instructions, loads it into memory, sets the instruction pointer to the beginning of the program, and then runs it. Pretty neat.

Want to learn more about the assembler? This is going to be the first in a series of articles, but in the meantime, the best resource is in the SourcePoint Academy: https://www.asset-intertech.com/resources/academy/sourcepoint-academy/sourcepoint-help.