struct or class in assembly - class

I need something like struct or class in c++
For example I need a class with an array and two attribute (size and len) and some function like append and remove .
How can I implement this in assembly with macros and procedures?

Tasm supports eg.
struc String // note: without 't' at the end
size dw 100
len dw 10
data db 0 dup(100)
ends String
Gnu assembler also has a .struct directive.
The syntax for MASM is:
String STRUCT
size dw 100
len dw 10
String ENDS
Usage again from the same MASM manual:
ASSUME eax:PTR String
mov ecx, [eax].size,
mov edx, [eax].len
ASSUME eax:nothing
.. or ..
mov ecx, (String PTR [eax]).size // One can 'cast' to struct pointer
One can also access a local variable directly
mov eax, myStruct.len

Here's a sample MASM struct from a HID interface routine that I wrote:
SP_DEVICE_INTERFACE_DATA struct
CbSize DWORD ?
ClassGuid GUID <>
Flags DWORD ?
Reserved ULONG ?
SP_DEVICE_INTERFACE_DATA ends

Structure in 8086 MASM
syntax
struct_name STRUC
var_name type ?
...
struct_name ENDS
Rules
1)It can't be initialized (If initialized results in garbage values)
2)It should be accessed using "direct addressing mode" (If not result in "immediate addressing mode")
program to add two numbers
DATA SEGMENT
FOO STRUC
A DB ?
B DB ?
SUM DW ?
FOO ENDS
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
XOR AX,AX
MOV DS:[FOO.A],0FFH
MOV DS:[FOO.B],0FFH
MOV AL,DS:[FOO.A] ;al=ff
ADD AL,DS:[FOO.B] ;al=al+ff
ADC AH,00H ;ah=ah+carry_flag(1/0)+00
MOV DS:[FOO.SUM],AX ;sum=ax
HLT ;stop
CODE ENDS
END START

Related

How to display the address of the function in WinDBG for .fnret command?

I need to get the address of the function required by .fnret command in WinDBG.
For example, I want to get the information about return value of apphelp!ApphelpCheckRunApp function.
First, I set a breakpoint on this function:
bp apphelp!ApphelpCheckRunApp
Then I'm continuing the execution, until it breaks on that function.
After breaking, I'm executing .fnret [Address] command.
I already tried to use the 77b345d5 address displayed on the breakpoint:
Breakpoint 0 hit
eax=77b345d5 ebx=7ed320f5 ecx=7ffac000 edx=7c886920 esi=7ffac000 edi=00000018
eip=77b345d5 esp=0378ce90 ebp=0378d108 iopl=0 nv up ei pl nz ac po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000213
appHelp!ApphelpCheckRunApp:
77b345d5 8bff mov edi,edi
but that seems to be not what I need, because I get the following error:
^ Unknown or unsupported return type in '.fnret 77b345d5'
Also I used return address 7c818cdf of this function from call stack (got via kb command):
ChildEBP RetAddr Args to Child
0283ce8c 7c818cdf 00000474 046bb7d0 00000000 appHelp!ApphelpCheckRunApp
but it leads me to the same error.
Which WinDBG command I should use for that and which return address it will display (in case it isn't displayed yet on breakpoint)? Will it then properly work for .fnret or .fnret /s commands? Unfortunately, there are no any examples of using them on MSDN, only the documentation.
Hoping on your help. Thanks in advance.
.fnret is only useful if you have private pdb
it is not useful if you have public pdb because it needs to retrieve the type information
here is a sample usage on a compiled code with private pdb
0:000> x /t /v /f myst!towlower
prv func 00007ff6`74ba5f84 7 <function> myst!towlower (unsigned short)
0:000> x /t /v /f myst!toupper
prv func 00007ff6`74b91b10 2a <function> myst!toupper (int)
0:000> .fnret myst!towlower
myst!towlower (00007ff6`74ba5f84) = unsigned short 1
0:000> .fnret myst!toupper
myst!toupper (00007ff6`74b91b10) = int 0n1
error on a known function which returns a HANDLE using public stripped pdb
0:000> .fnret KERNELBASE!CreateFileA
^ Unknown or unsupported return type in '.fnret KERNELBASE!CreateFileA'
success on a system file with private pdb
it casts the forced return value dumped in #rax as a typed return with value of a function with type information
a system file with prrivate pdb
0:000> .printf "%y\n" , 0x00000001`800bace0 ; an arbitrary function
ole32!ToUnicode (00000001`800bace0)
0:000> .printf "%mu\n" , 00000001`8014c17a ; an arbitrary wide string
guageErrorPointerą“‚Š
0:000> r rax = 00000001`8014c17a the $retreg is populated with an address of wide string
0:000> .fnret 0x00000001`800bace0 << fnret casts the $retreg as wide string and prints the resulting widestring
ole32!ToUnicode (00000001`800bace0) = wchar_t * 0x00000001`8014c17a
"guageErrorPointer???"
OK, that command is indeed not helpful at all when using public PDBs.
I found better solution here: How to get return value from a function in windbg?.
It is possible to get the memory address of return value by viewing eax/rax register on x86/x64 appropriately, using r command (since it always is stored there). After breakpoint, I'm just typing r eax on x86 or r rax on x64. Output will be look like this:
eax=[Address]
Then, I'm displaying a value of received memory address via d* (dd, du etc. displaying data types commands), like this:
du [Address]
After looking at the output, it becomes understandable which data is returned, and its data type also (at least in most of cases).
But to understand first, which data type is used, I'm trying the different combinations of display memory commands and display referenced memory commands.

How to hide auto-generated comments?

When disassembling in Radare2, the output is decorated with random annotations of memory peeks, decimal conversions, etc., for example:
...
0000:06ea and al, 0x7f
0000:06ec cmp al, 5 ; 5
0000:06ee jne 0x712
0000:06f0 mov eax, dword [bx + 8] ; [0x8:4]=-1 ; 8
0000:06f4 mov edx, dword [bp + 0x14] ; [0x14:4]=-1 ; 20
...
I find them largely irrelevant: for example, I don't care about the value at 0x14 when that is used as a displacement rather than a fixed address. What command do I use to hide them, either globally or for a particular address?
This is possible since version 3.0. The commands are:
e asm.comments=false
e asm.usercomments=true
The former turns all comments off and the latter overrides this for user-added comments. Currently there's no finer distinction than this: you can't turn off the [0x8:4]=-1 keeping the decimal conversions only, for example.

MASM: dereference struct pointer twice?

I've been dabbling in x86 assembly again using MASM, and ran into a small roadblock. Looking to reinvent the wheel out of pure enjoyment.
ASSUME eax:PTR hostent
mov ebx, [eax].h_addr_list ;this doesn't compile -- but IDE recognizes hostent.h_addr_list
;I think I need to dereference the pointer twice, but I have no clue how to do that with MASM.
;It sounds silly, yes, but doing the traditional mov eax, [eax] won't solve my compiler error
mov ecx, [eax].h_name ;this compiles just fine
;mov ebx, (hostent PTR [eax]).h_addr_list ;didn't work either.
ASSUME eax:nothing
The problem seems to be that h_addr_list is a char **, while h_name is a char *. The error thrown is:
error A2006: undefined symbol : h_addr_list
The definition for the hostent structure is:
typedef struct hostent {
char FAR *h_name; //note the char FAR *
char FAR FAR **h_aliases;
short h_addrtype;
short h_length;
char FAR FAR **h_addr_list; //note the char FAR FAR **
} HOSTENT, *PHOSTENT, FAR *LPHOSTENT;
I strongly suspect you are using MASM32 and have a line like this:
include \masm32\include\windows.inc
windows.inc contains the HOSTENT structure:
hostent STRUCT
h_name DWORD ?
h_alias DWORD ?
h_addr WORD ?
h_len WORD ?
h_list DWORD ?
hostent ENDS
Compare that to:
typedef struct hostent {
char FAR *h_name; //note the char FAR *
char FAR FAR **h_aliases;
short h_addrtype;
short h_length;
char FAR FAR **h_addr_list; //note the char FAR FAR **
} HOSTENT, *PHOSTENT, FAR *LPHOSTENT;
You'll notice that h_addr_list is defined in windows.inc as h_list. You could either modify windows.inc and rename h_list or you can modify your code to reference h_list instead of h_addr_list. I would do the latter as it would keep your code compatible with others using MASM32.
It should also be clear that some of the other fields are named a bit differently as well.

Is there a way to dump the individual arguments of va_list in windbg?

Is there a way to dump the arguments in va_list in windbg given the format string and the starting address of va_list?
I usually do this by just dumping the content of the stack using command dd esp (for x86) or dq rsp (for x64). Knowing the starting address of va_list makes it a bit easier to locate the place in the stack where vararg block begins, but usually you can either guess it or calculate by knowing the sizes of regular (non-vararg parameters) to the function.
Here is an annotated example for x86. The function beeing called:
printf("%d %o %g %s %c", 101, 201, 301.0, "401-string", '5');
in debugger:
0:000> bp MSVCR100D!printf
0:000> g
Breakpoint 1 hit
eax=00000001 ebx=00000000 ecx=2549afc4 edx=00000000 esi=002ceeb8 edi=002cf040
eip=0ff57ee0 esp=002cee98 ebp=002cf04c iopl=0 nv up ei pl nz ac po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000212
MSVCR100D!printf:
0ff57ee0 8bff mov edi,edi
0:000> dd /c1 esp
002cee98 01365cee // return address
002cee9c 0137d6e8 // pointer to the format string "%d %o %g %s %c" --> next follows our variable arguments
002ceea0 00000065 // first vararg argument, int 101
002ceea4 000000c9 // second vararg argument, int 201
002ceea8 00000000 // third vararg argument, double 301.0, it occupies two slots in stack
002ceeac 4072d000 // third argument continues
002ceeb0 0137d70c // fourth vararg argument, pointer to string
002ceeb4 00000035 // fifth vararg argument, 8-bit character (still occupies 4 bytes in stack)
002ceeb8 25b87244
002ceebc 002cf254
002ceec0 0041c520
002ceec4 00000000
...
For other functions it will be very similar, because all functions that use variable number of arguments have to be following __cdecl calling convention, so you will find the same type of layout of parameters in the stack.

Alternative for DWORD in Objective C

I am trying opening a audio file (.wav) and retrieve the raw data. I got the below code from the link. When I am trying to implement the code DWORD is not supported in Objective c.
How can I implement this?
FILE *fp;
fp = fopen("sound.wav","rb");
if (fp)
{
BYTE id[4]; //four bytes to hold 'RIFF'
DWORD size; //32 bit value to hold file size
fread(id,sizeof(BYTE),4,fp); //read in first four bytes
if (!strcmp(id,"RIFF"))
{ //we had 'RIFF' let's continue
fread(size,sizeof(DWORD),1,fp);
//read in 32bit size value
}
}
You could use any 32-bit unsigned integer value for DWORD, e.g. uint32_t.
#include <stdint.h>
typedef uint32_t DWORD;
...