News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

help about native api

Started by jangogrand, August 11, 2017, 09:55:10 AM

Previous topic - Next topic

aw27

Quote from: hutch-- on August 11, 2017, 04:00:23 PM
aw,
I built your version but it does not run on my Win10 64. Builds OK, just does nothing.

Hutch,

This works in windows 10 64-bit, now i use ExitProcess.
You don't need to use GetProcAddress, the function has been around since Windows 2000.


.386

.model Flat, STDCALL
option Casemap :None

TRUE equ 1

includelib \masm32\lib\ntdll.lib
RtlCompareString PROTO STDCALL :ptr,:ptr,:BYTE

includelib \masm32\lib\msvcrt.lib
printf PROTO C :ptr, :vararg

includelib \masm32\lib\kernel32.lib
ExitProcess proto :dword

_STRING struct
_Length word ?
_Maximumlength word ?
_Buffer dword ?
_STRING ends

.data
s1 db "abcd" ;
s2 db "Bbcd" ;
format db 'result: %d',13,10,0

.code

main proc
LOCAL str1 : _STRING
LOCAL str2 : _STRING

mov str1._Length, LENGTHOF s1
mov str1._Maximumlength, LENGTHOF s1
mov eax, offset s1
mov str1._Buffer, eax

mov str2._Length, LENGTHOF s2
mov str2._Maximumlength, LENGTHOF s2
mov eax, offset s2
mov str2._Buffer, eax

INVOKE RtlCompareString, addr str1, addr str2, TRUE

INVOKE printf, addr format, eax ; should display negative

INVOKE ExitProcess,0
main endp

end main

hutch--

 :biggrin:

This revelation does not make either yours or mine work in win 10 64 bit.  :P

aw27

Quote from: hutch-- on August 11, 2017, 05:03:32 PM
:biggrin:

This revelation does not make either yours or mine work in win 10 64 bit.  :P

Mine works in "my" Windows 10 64-bit Build 15063.483  Version 1703
I built it with 100% Genuine ™ Microsoft ® products, namely MASM.EXE and LINK.EXE :lol:

jangogrand

thank you aw27 it work fine  :t

hutch--

shrug,

Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

Doesn't work here.

LATER : The exit process fixed it.

K:\asm32\RtlCmpStr\aw>aw
result: -1


jj2007

Quote from: jangogrand on August 11, 2017, 11:15:08 AMur program when i open it with ollydbg it give eax >0 when the 2 string are same and that is not the correct result

Quote from: jangogrand on August 11, 2017, 11:21:37 AM
jj2007 the program is not displaying any result

Did you assemble it as console app?

Did you understand this line?
Src1a dw 5, 5 ; min, max

My example may be "pure crap", as aw27 puts it in his usual educated style of communication, but it works perfectly. It even returns 0 for the case-insensitive comparison of abcd vs ABCD, but you must understand the min, max line above. And you would certainly understand it if you had followed my advice to google for "counted strings". Now, please answer my question why you want to use the native API. Or better: Why do you want to use the native API, are the CRT functions not available?

P.S.: The 64-bit equivalent - project attached.include \Masm32\MasmBasic\Res\JBasic.inc ; ## 64-bit demo, builds with ML and UAsm ##
.data
Src1a dd 5, 5 ; min, max
dq Src1
Src1 db "abcde", 0
Src2a dd 5, 5
dq Src2
Src2 db "ABCDE", 0
.code
Init
  Print Chr$("This code was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format", 13, 10, 10)
  jinvoke RtlCompareString, addr Src2a, addr Src1a, 0
  Print Str$("%i returned\n", rax)
  jinvoke RtlCompareString, addr Src2a, addr Src1a, 1
  Inkey Str$("%i returned\n", rax)
EndOfCode


Output:
This code was assembled with ml64 in 64-bit format

-32 returned
0 returned

aw27

The example is pure crap because:
1) it does not evidence that you are dealing with a structure.
2) You are using NULL terminated strings which proves that you simply don't know what counted string are used for.
3) There is no min and max. There is the size of the string and the maximum number of characters in the buffer.
4) It is ridiculous to ask "why do you want this? Is it for malware production?". Come on, not everybody is in the Charles Petzold era, you must not assume that people that want to know more than you are producing ramsonware.

jj2007

Note that in the 64-bit example the min max fields are DWORDs, while they are WORDs in 32-bit land.

A short and crispy explanation of counted strings is here.

Quote from: aw27 on August 11, 2017, 07:02:29 PMyou must not assume that people that want to know more than you are producing ramsonware.

You are young and naive, José. And uneducated :greensml:


TWell

RtlCompareString uses
https://msdn.microsoft.com/en-us/library/windows/hardware/ff540605(v=vs.85).aspx
typedef struct _STRING {
  USHORT Length;
  USHORT MaximumLength;
  PCHAR  Buffer;
} ANSI_STRING, *PANSI_STRING;


RtlCompareUnicodeString uses
https://msdn.microsoft.com/en-us/library/windows/desktop/aa380518(v=vs.85).aspx
typedef struct _LSA_UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;
  PWSTR  Buffer;
} LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;


EDIT: in NtDef.htypedef struct _STRING {
    __maybevalid USHORT Length;
    __maybevalid USHORT MaximumLength;
#ifdef MIDL_PASS
    [size_is(MaximumLength), length_is(Length) ]
#endif // MIDL_PASS
    __field_bcount_part_opt(MaximumLength, Length) PCHAR Buffer;
} STRING;
typedef STRING *PSTRING;
typedef STRING ANSI_STRING;
typedef PSTRING PANSI_STRING;

jangogrand

thank you  aw27  , now i try to use LoadLibraryA :


.386
.model flat, stdcall
option casemap:none
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\user32.lib
includelib C:\masm32\lib\ntdll.lib
includelib C:\masm32\lib\msvcrt.lib
include C:\masm32\include\kernel32.inc  ;cotient les prototype des function
include C:\masm32\include\user32.inc
include C:\masm32\include\windows.inc
RtlCompareString PROTO STDCALL :ptr,:ptr,:BYTE
printf PROTO C :ptr, :vararg
ExitProcess proto :dword
TRUE equ 1
_STRING struct
   _Length word ?
   _Maximumlength word ?
   _Buffer dword ?
_STRING ends

.data
lMod dd ?
s1 db "abcdpom" ;
s2 db "abcd" ;
format db 'result: %d',13,10,0
Fapi db "RtlCompareString",0
Flib db "ntdll",0

.code

main proc
   LOCAL str1 : _STRING
   LOCAL str2 : _STRING
   
   mov str1._Length, LENGTHOF s1
   mov str1._Maximumlength, LENGTHOF s1
   mov eax, offset s1
   mov str1._Buffer, eax
   
   mov str2._Length, LENGTHOF s2
   mov str2._Maximumlength, LENGTHOF s2
   mov eax, offset s2
   mov str2._Buffer, eax
   

invoke LoadLibraryA, OFFSET Flib
invoke GetProcAddress, eax, OFFSET Fapi
mov lMod,eax

push  str1
push  str2
push 1
call lMod
   
   INVOKE printf, addr format, eax ; should display negative
   
   INVOKE ExitProcess,0
main endp

end main

i get error about "push  str1 " ad "push  str2"  i have also try offset but i still get the error

jangogrand

 jj2007  iam not try to make some malware , is only for education

aw27


I can not test more (JJ can assist you  :badgrin:), but it appears that you are pushing the parameters in the wrong order, i.e left to right.

jj2007

Quote from: TWell on August 11, 2017, 07:29:01 PM
RtlCompareString uses
https://msdn.microsoft.com/en-us/library/windows/hardware/ff540605(v=vs.85).aspx
typedef struct _STRING {
  USHORT Length;
  USHORT MaximumLength;
  PCHAR  Buffer;
} ANSI_STRING, *PANSI_STRING;

Interesting, Tim, but my tests show that the MSDN info is incorrect; in x64, the size of USHORT is still 16 bits, but that fails miserably with RtlCompareString. It would be interesting to see a C 64-bit example, with an _asm int 3; inserted before the RtlCompareString(). Your turn - as you know, jj is not a C programmer  :bgrin:

Quote from: jangogrand on August 11, 2017, 07:36:43 PM
jj2007  iam not try to make some malware , is only for education

Bien sur. On attend une description plus détaillée du "projet d'éducation" ;-)

jangogrand

 jj2007  il faut m'aider , c'est pour connaitre utiliser native api c'est tout

jj2007

Re 64-bit version, this is more correct:
Src1a dw 5, 5 ; current len, maxlen
dd ? ; padding
dq Src1
Src1 db "abcde", 0


So it seems the ANSI_STRING structure is, well, QWORD-aligned in x64 8)

Under the hood:000000007771DA18 | 0F B7 31                          | movzx esi, word ptr ds:[rcx]          | 2nd string, current len
000000007771DA1B | 44 0F B7 2A                       | movzx r13d, word ptr ds:[rdx]         | 1st string, current len
000000007771DA1F | 4C 8B 59 08                       | mov r11, qword ptr ds:[rcx+8]         | [rcx+8]:"ABCDE"
000000007771DA23 | 48 8B 5A 08                       | mov rbx, qword ptr ds:[rdx+8]         | [rdx+8]:"abcde"


So, here is a formally correct example for 64-bit land (tested, it works fine):

include \Masm32\MasmBasic\Res\JBasic.inc        ; # 64-bit demo, builds with ML and UAsm #
.data
Src1    db "abcde", 0
Src2    db "ABCDE", 0

ANSI_STRING STRUCT              ; MSDN: Driver Reference
_Length        USHORT ?
MaximumLength  USHORT ?
Buffer         PCHAR ?
ANSI_STRING ENDS

AnsiString1     ANSI_STRING <5, 5, Src1>
AnsiString2     ANSI_STRING <5, 5, Src2>

Init
  Print Chr$("This code was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format", 13, 10, 10)
  jinvoke RtlCompareString, addr AnsiString1, addr AnsiString2, 0
  Print Str$("%i returned\n", rax)
  jinvoke RtlCompareString, addr AnsiString1, addr AnsiString2, 1
  Inkey Str$("%i returned\n", rax)
EndOfCode


This code was assembled with ml64 in 64-bit format

32 returned
0 returned


Btw Google shows no sign of life for RtlCompareString, it seems to be the most exotic function on Earth. In which educational context do you want to use it, jango? I am impressed that although you can't push arguments in the right order, you are already studying Kernel mode driver functions :t