Assembly Language Day 05

0x00

This chapter is dedicated to daily learning and note sharing to help everyone learn assembly language. Why learn assembly language? Because in red-blue confrontations, our tools are often detected and eliminated due to the presence of AV/EDR. Therefore, we need to counter AV, which involves evasion techniques. To learn evasion techniques, we must start from the basics. In the future, I may also share notes on C++, PE file structures, etc. Additionally, I might introduce knowledge related to reverse engineering.

0x01

Assignment 1:

assume cs:code
code segment
  mov ax,0
  mov cx,236
s:
  add ax,123
  loop s

  mov ax,4c00h
  int 21h
code ends
end

Assignment 2:

assume cs:codesg
codesg segment
  mov ax,200h
  mov ds,ax
  mov bx,0
  mov cx,64
s:
  mov ds:[cx],cx
  inc bx
  loop s

  mov ax,4c00h
  int 21h
codesg ends
end

5. Programs with Multiple Segments

The previous programs only had one code segment. If a program needs to use other space to store data, the safe space 0:200~02ff is only 256 bytes, which may not be sufficient.

In the operating system environment, the space obtained legally through the operating system is safe. One way is to allocate space for the program when loading, and another is to request space from the system during execution. We will not discuss the second method in our learning.

If we want a program to obtain the required space when loaded, we must specify this in the source program by defining a segment to acquire memory space.

Using Data in the Code Segment

Consider the problem: programming calculation 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h The sum of these eight numbers, with the result stored in ax.

In previous lessons, we accumulated data from memory units without caring about the data itself. We want to accumulate the values of the given data, so we hope to use a loop to accumulate. Therefore, we need to store the data in a group of contiguous memory units.

To achieve this, we can use instructions to send them one by one into contiguous memory units. But where do we find this segment of memory? We cannot decide ourselves; we should let the operating system allocate it for us.

We can define the data we want to process in the program. This data is compiled and linked as part of the executable file. When the executable file is loaded into memory, this data is also loaded into memory, and the data to be processed naturally obtains storage space.

assume cs:code
code segment
  dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h

  mov bx,0
  mov ax,0

  mov cx,8
s:
  add ax,cs:[bx]
  add bx,2
  loop s

  mov ax,4c00h
  int 21h
code ends
end

In the first line of the program, dw means define word, which defines 8 word-sized data, occupying a total of 16 bytes of memory space.

Instructions in the program will accumulate these 8 data. Since they are in the code segment, the segment address of the code segment is stored in cs during program execution, so we can obtain their segment address from cs. Since the data defined by dw is located at the beginning of the code segment, the offset addresses are 0, 2, 4, 6, 8, A, C, and E respectively.

In the program, bx stores the incremented offset address by 2, and a loop is used to accumulate. Before the loop starts, (bx) is set to 0, and cs:bx points to the first data word. In each loop, (bx) is updated to (bx)+2, and cs:bx points to the next data word.

However, the entry point of the program is not the command we want to execute. We can specify the entry point in the source program.

assume cs:code
code segment
  dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
start:
  mov bx,0
  mov ax,0

  mov cx,8
s:
  add ax,cs:[bx]
  add bx,2
  loop s

  mov ax,4c00h
  int 21h
code ends
end start

We add the label start before the first instruction of the program. This label appears after the pseudo-instruction end, which means that end not only indicates the end of the program but also informs the compiler that the entry point is at start.

In a single-task system, the execution process of the program in the executable file is as follows:

  • Since other programs load the executable file into memory
  • Set CS:IP to execute the program’s entry point
  • After the program ends, return to the loader

Thus, we can arrange the framework of the program:

assume cs:code
code segment
  Data
start:
  Code
code ends
end start

Using Segments in the Code Segment

Complete the following program, using the stack to store the defined data in reverse order.

assume cs:codesg
codesg segment
  dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h	
  ?
codesg ends
end

The general idea is as follows:

When the program runs, the defined data is stored in CS:0~CS:F units. We sequentially push the data from these 8 word units onto the stack, and then pop them back into these 8 word units to achieve the reverse storage of data. The problem is that we first need a segment of memory space that can be used as stack space, which should be allocated by the operating system. We can obtain a segment of space by defining data in the program and then use it as stack space.

assume cs:codesg
codesg segment
  dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
  dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  // Define 16 word-sized data with dw, which will obtain 16 words of memory space after the program is loaded.
start:
  mov ax,cs
  mov ss,ax
  mov sp,30h     // Set the stack top ss:sp to point to cs:30

  mov bx,0
  mov cx,8

s:
  push cs:[bx]
  add bx,2
  loop s

  mov bx,0
  mov cx,8
s0:
  pop cs:[bx]
  add bx,2
  loop s0

  mov ax,4c00h
  int 21h

codesg ends
end start 

Placing Data, Code, and Stack in Different Segments

Placing code and data in one segment seems chaotic. If the stack and the space required by code and data exceed 64KB, they cannot be stored in one segment. Therefore, just as we define a code segment, we define multiple segments, within which we define the required data or define data to obtain stack space.

assume cs:code,ds:data,ss:stack

data segment
	dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data ends

stack segment
	dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
stack ends

code segment

start: mov ax,stack
		mov ss,ax
		mov sp,20h

		mov ax,data
		mov ds,ax

		mov bx,0

		mov cx,8
s:   push [bx]
		add bx,2
		loop s

		mov bx,0

		mov cx,8
s0: pop [bx]
		add bx,2
		loop s0

		mov ax,4c00h
		int 21h

code ends
end start

Referencing Segment Addresses

Now the program has multiple segments, and the segment name acts as a label representing the segment address. Therefore, mov ax, data means to load the segment address of the data segment into ax. When referencing the address of 0abch in the data segment, which is data:6, to load it into bx, we need:

mov ax,data
mov ds,ax
mov bx,ds:[6]

The code segment, data segment, and stack segment are all arranged by us, and the CPU does not recognize them. The assume directive is a pseudo-instruction, and cs, ds, ss will not connect with code, data, and stack segments. If we change it to the following form, the computer will process the result the same:

assume cs:b,ds:a,ss:c

a segment
	dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
a ends

c segment
	dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
c ends

b segment

d: mov ax,c
		mov ss,ax
		mov sp,20h

		mov ax,a
		mov ds,ax

		mov bx,0

		mov cx,8
s:   push [bx]
		add bx,2
		loop s

		mov bx,0

		mov cx,8
s0: pop [bx]
		add bx,2
		loop s0

		mov ax,4c00h
		int 21h

b ends
end d

0x02

Previous Notes:

Assembly Language Day 04

Assembly Language Day 03

Assembly Language Day 02

Assembly Language Day 01

Basic Knowledge of Assembly Language

Previous Practices:

Domain Forest Breach from the Red Team Perspective: A Cross-Domain Control Attack and Defense Triggered by Shiro Deserialization

Practice – From Shiro Deserialization to Domain Control

“Nuclear Explosion Effect” After Domain Control Takeover: Permission Harvesting of 1600 Hosts Based on DCSync and Golden Ticket

Assembly Language Day 05ShareAssembly Language Day 05CollectAssembly Language Day 05ViewAssembly Language Day 05Like

Assembly Language Day 05

Scan to Follow UsBecome an Excellent Network Security Guard

Leave a Comment