Author Topic: Beep without API  (Read 8993 times)

Magnum

  • Member
  • *****
  • Posts: 2308
Beep without API
« on: October 18, 2014, 08:46:38 AM »
.data?

assume fs:nothing

This is supposed to beep without using an API but does not work.

.code

start:

 mov eax, 1002; Index here (This is MessageBeep)
  mov ecx, 0; Or xor it, whatever
  lea edx, [esp+4]; Load edx with the value here
  call dword ptr fs:[0C0h]; Jump to transparency layer and get your beep
Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

Mikl__

  • Member
  • ****
  • Posts: 802
Re: Beep without API
« Reply #1 on: October 18, 2014, 03:07:54 PM »
Hi, Magnum!
for different versions and builds Windows this index will be different. I have Windows XP ver 2008 serv pack 3
Code: [Select]
push 31h
push 0;parametr for MessageBeep
push offset @f
mov eax,1143h <-- Index of MessageBeep in WinXP
push offset @f
mov edx,esp
sysenter
@@: add esp,12;clear parametrs

Magnum

  • Member
  • *****
  • Posts: 2308
Re: Beep without API
« Reply #2 on: October 19, 2014, 07:50:07 AM »
sysenter gives syntax error.

I found this.

Code: [Select]
INTEL: SYSENTER/SYSEXIT
Description

"Executes a fast call to a level 0 system procedure or routine. SYSENTER is a companion instruction to SYSEXIT.
The instruction is optimized to provide the maximum performance for system calls from user code running at privilege level 3 to
operating system or executive procedures running at privilege level 0." -- Intel IA-32 (64) programming manual, volume 2B.
Registers
MSRs

These must be accessed through rdmsr and wrmsr

    IA32_SYSENTER_CS (0x174) - base ring 0 code segment. Ring 0 data = CS + 8, Ring 3 code = CS + 16, Ring 3 data = CS + 24.

These values cannot be changed, therefore your GDT must be structured as such.

    IA32_SYSENTER_ESP (0x175) - The kernel's ESP for SYSENTER.
    IA32_SYSENTER_EIP (0x176) - The kernel's EIP for SYSENTER. This is the address of your SYSENTER entry point.
Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

Mikl__

  • Member
  • ****
  • Posts: 802
Re: Beep without API
« Reply #3 on: October 20, 2014, 11:50:31 AM »
Hi, Magnum!
I did the following - write a program consisting invoke MessageBeep, 0, and threw it under the debugger, I saw the following
Code: [Select]
push 0
call dword ptr ds:[user32.MessageBeep]
I went inside the function MessageBeep and saw
Code: [Select]
mov edi,edi
push ebp
mov ebp,esp
push 31h
push dword ptr ss:[ebp+8]<-- argument for MessageBeep = 0
call 7E3684AEh
pop ebp
retn 4
I went inside the function 7E3684AEh and saw
Code: [Select]
mov eax,1143h
mov edx,7FFE0300
call dword ptr ds:[edx]; ntdll.KiFastSystemCall
retn 8
I went inside the function 7FFE0300h and saw
Code: [Select]
mov edx,esp
sysenter
after that, I wrote a program
Code: [Select]
push 31h
push 0;parametr for MessageBeep
push offset @f
mov eax,1143h <-- Index of MessageBeep in WinXP
push offset @f
mov edx,esp
sysenter
@@: add esp,12;clear parametrs

Magnum

  • Member
  • *****
  • Posts: 2308
Re: Beep without API
« Reply #4 on: October 20, 2014, 12:44:19 PM »
Thanks for your analysis.

How did you go inside MessageBeep ?

I use Ollydbg.

I have searched but can't find any assembly examples that use sysenter.

Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

Mikl__

  • Member
  • ****
  • Posts: 802
Re: Beep without API
« Reply #5 on: October 20, 2014, 04:06:49 PM »
I use Ollydbg too, in most cases the trace program, press the button F8 but when the cursor reaches the desired procedure clicks on F7 and you will get into the procedure

six_L

  • Member
  • **
  • Posts: 160
Re: Beep without API
« Reply #6 on: October 20, 2014, 05:56:33 PM »
1,the Ollydbg uses for user mode. Windbg uses for kernel mode.
2,"Beep without API" means that you'll write your code for beep. it must be used "in, out" instruction operate the hardware. on the user mode, the instruction can't be allowed to operate. so you need to create your own system driver. f-four has written a tutorial for it.

GoneFishing

  • Member
  • *****
  • Posts: 1071
  • Gone fishing
Re: Beep without API
« Reply #7 on: October 21, 2014, 05:47:18 AM »
Does anybody know if there're other APIs which can be called like MessageBeep  ?
As above mentioned function has index 1143 , I suspest it's not the only one .

Very nice topic, Andy  :t

adeyblue

  • Member
  • **
  • Posts: 89
    • Airesoft
Re: Beep without API
« Reply #8 on: October 21, 2014, 07:36:40 AM »
Does anybody know if there're other APIs which can be called like MessageBeep  ?

All calls which have processing in kernel mode are called this way: Here's the Win7 lists. Just beware that the numbers can change with each OS and its bitness (XP x64 might not be the same as XP x86 is what I mean).

Mikl__

  • Member
  • ****
  • Posts: 802
Re: Beep without API
« Reply #9 on: October 21, 2014, 10:54:43 AM »
Quote
All calls which have processing in kernel mode are called this way: Here's the Win7 lists. Just beware that the numbers can change with each OS and its bitness (XP x64 might not be the same as XP x86 is what I mean).
I wrote about in in my message
Quote
for different versions and builds Windows this index will be different.
Index of WinAPI-function can be found empirically and I showed how to do it

GoneFishing

  • Member
  • *****
  • Posts: 1071
  • Gone fishing
Re: Beep without API
« Reply #10 on: October 21, 2014, 07:01:15 PM »
Thank you , adeyblue  :t
That's very valuable post . In the comments author says that ssdt can be dumped in windbg .

GoneFishing

  • Member
  • *****
  • Posts: 1071
  • Gone fishing
Re: Beep without API
« Reply #11 on: October 22, 2014, 01:46:35 AM »
Well, after all I made it work on my WinXP SP3  box:
Code: [Select]
include \masm32\include\masm32rt.inc

.code
        start:
               ; KiUserCallbackDispatcher function, executed  after  sysenter
               ; instruction, wants user32 library to be linked to our app

               invoke InitCommonControls ; little trick for linking user32 lib

               push    31h
               push 0
               mov     eax,1143h   
               push offset @f
               push offset @f
           
               mov     edx, esp
               dw 340fh          ;  sysenter opcode , to bypass the syntax error 

        @@:
               add esp,12
               inkey
               exit
end start

...
This is supposed to beep without using an API but does not work.
...
  mov ecx, 0 ; Or xor it, whatever
  lea edx, [esp+4]; Load edx with the value here
  call dword ptr fs:[0C0h]; Jump to transparency layer and get your beep
This code is for 64bit versions of Windows (so I didn't test it - I'm on 32bit now )

Mikl__

  • Member
  • ****
  • Posts: 802
Re: Beep without API
« Reply #12 on: October 22, 2014, 01:27:43 PM »
Different ways of creating MessageBox
It would seem that it may be easier function MessageBox? - only function MessageBeep Will try to find out what is inside the MessageBox? Maybe this will help make our programs even less. Run the program where MessageBox displayed in the debugger Ollydbg and the moment when the cursor reaches the line call MessageBoxA not push F8 (Step over), and the key F7 (Step into) and end up inside the function MessageBoxA - is going on here recoding ASCII-header rows and text messages in UNICODE and function call MessageBoxW, again click on F7 - is inside MessageBoxW is function MessageBoxExA which has one parameter more than MessageBoxA and MessageBoxW and this parameter (dwLanguageId) is 0 (LANG_NEUTRAL), the rest are parameters coincide completely. Inside there is a function MessageBoxExA is MessageBoxExW. Inside MessageBoxExW is function MessageBoxTimeoutA in which one parameter is more than this parameter and MessageBoxExW (Timeout) -1. Inside MessageBoxTimeoutA, as you might guess MessageBoxTimeoutW. Inside MessageBoxTimeoutW is MessageBoxIndirectA, this feature allows you to change the icon at MessageBox and may cause the Help, but we leave these parameters to zero. Inside MessageBoxIndirectA is exactly the same but with UNICODE strings function MessageBoxIndirectW is SoftModalMessageBox In programm of Indy/Clerk I found a link to NtRaiseHardError - MessageBox call at the kernel level
Code: [Select]
; masm windows gui #
.686P
.model flat
include windows.inc
include w2k\native.inc
include w2k\ntstatus.inc
includelib user32.lib
includelib ntdll.lib
extern _imp__MessageBoxA@16:dword
extern _imp__MessageBoxW@16:dword
extern _imp__MessageBoxExA@20:dword
extern _imp__MessageBoxExW@20:dword
extern _imp__MessageBoxTimeoutA@24:dword
extern _imp__MessageBoxTimeoutW@24:dword
extern _imp__SoftModalMessageBox@4:dword
extern _imp__MessageBoxIndirectA@4:dword
extern _imp__MessageBoxIndirectW@4:dword
extern _imp__NtRaiseHardError@24:dword
;extern _imp__KiFastSystemCall@0:dword
.code
start: xor ebx,ebx
mov esi,ebx
push MB_ICONASTERISK or MB_OK
push offset MsgCaption
push [Msg+esi*4]
push ebx
call _imp__MessageBoxA@16
;---------------------------------------
inc esi
push MB_ICONASTERISK or MB_OK
push offset TitleText
push [Msg+esi*4]
push ebx
call _imp__MessageBoxW@16
;----------------------------------------
inc esi
push ebx
push MB_ICONASTERISK or MB_OK
push offset MsgCaption
push [Msg+esi*4]
push ebx
call _imp__MessageBoxExA@20
;-----------------------------------------
inc esi
push ebx
push MB_ICONASTERISK or MB_OK
push offset TitleText
push [Msg+esi*4]
push ebx
call _imp__MessageBoxExW@20
;-----------------------------------------
inc esi
        push -1
        push ebx
        push MB_ICONASTERISK or MB_OK
        push offset MsgCaption
        push [Msg+esi*4]
        push ebx
        call _imp__MessageBoxTimeoutA@24
;------------------------------------------
inc esi
        push -1
        push ebx
        push MB_ICONASTERISK or MB_OK
        push offset TitleText
        push [Msg+esi*4]
        push ebx
        call _imp__MessageBoxTimeoutW@24
;------------------------------------------
        sub esp,sizeof(MSGBOXPARAMSA);40
mov edi,esp
assume edi:ptr MSGBOXPARAMSA
mov dword ptr [edi].cbSize,sizeof(MSGBOXPARAMSA)
mov dword ptr [edi].hwndOwner,ebx
mov dword ptr [edi].hInstance,400000h
mov dword ptr [edi].lpszText,offset Msg8
mov dword ptr [edi].lpszCaption,offset MsgCaption
mov dword ptr [edi].dwStyle,MB_ICONASTERISK or MB_OK
mov dword ptr [edi].lpszIcon,ebx;:= PCHAR('MYICO');
mov dword ptr [edi].dwContextHelpId,ebx;:= 0;
mov dword ptr [edi].lpfnMsgBoxCallback,ebx;:= nil;
mov dword ptr [edi].dwLanguageId,ebx;:= LANG_NEUTRAL;
push edi
        call _imp__MessageBoxIndirectA@4
;--------------------------------------------------------
mov dword ptr [edi].lpszText,offset Msg9
mov dword ptr [edi].lpszCaption,offset TitleText
push edi
        call _imp__MessageBoxIndirectW@4
add esp,sizeof(MSGBOXPARAMSA)
;-------------------------------------------------------------------------
 MSGBOXDATA struct       
     params              MSGBOXPARAMSA <>
     pwndOwner           DWORD ?
     wLanguageId         DWORD ?
     pidButton           DWORD ?         ; // Array of button IDs
     ppszButtonText      DWORD ?         ; // Array of button text strings
     cButtons            DWORD ?
     DefButton           DWORD ?
     CancelId            DWORD ?
     Timeout             DWORD ?
 MSGBOXDATA ends

        sub esp,sizeof MSGBOXDATA+0Ch
;  local mbd:MSGBOXDATA
;  local bufid[1]:DWORD
;  local bufstr[1]:DWORD
lea eax,[esp+4];bufid
mov dword ptr[eax],1
mov [esp],offset _OK
        lea edi,[esp+8]
mov [edi].cbSize,sizeof MSGBOXPARAMSA
mov [edi].hwndOwner,ebx
mov [edi].lpszText,offset Msg7
mov [edi].lpszCaption,offset TitleText
mov [edi].dwStyle,MB_ICONASTERISK or MB_OK
        assume edi:ptr MSGBOXDATA
mov [edi].pwndOwner,ebx;0
mov [edi].wLanguageId,ebx;0
mov [edi].pidButton,eax
mov [edi].ppszButtonText,esp;offset bufstr
mov [edi].cButtons,1
mov [edi].DefButton,ebx;0
mov [edi].CancelId,1
mov [edi].Timeout,-1
push edi
call _imp__SoftModalMessageBox@4
assume edi:nothing
add esp,sizeof MSGBOXDATA+0Ch
;------------------------------------------------------------------
ShowMessage proc
Local MessageBuffer[60h]:WCHAR;в Num+Num1 in words;push ebp
Local Message[2]:UNICODE_STRING;mov ebp,esp
Local HardErrorPointer[3]:PVOID;sub esp,0DCh
;the first parameter
lea edi,MessageBuffer;lea edi,[ebp-0C0h]
mov Message.Buffer+sizeof(UNICODE_STRING)*0,edi;mov [ebp-0CCh],edi
mov Message.MaximumLength+sizeof(UNICODE_STRING)*0,Num;mov word ptr[ebp-0CEh],22h
mov Message._Length+sizeof(UNICODE_STRING)*0,Num-2;mov word ptr[ebp-0D0h],20h
lea edx,Message+sizeof(UNICODE_STRING)*0;lea edx,[ebp-0D0h]
mov HardErrorPointer+sizeof(PVOID)*0,edx;pwText;mov [ebp-0DCh],edx
mov esi,offset MessageText
mov ecx,Num+Num1;mov ecx,62h
rep movsb
;the second parameter
lea edi,MessageBuffer+Num;lea edi,[ebp-9Eh]
mov Message.Buffer+sizeof(UNICODE_STRING)*1,edi;mov [ebp-0C4h],edi
mov Message.MaximumLength+sizeof(UNICODE_STRING)*1,Num1;mov word ptr[ebp-0C6h],40h
mov Message._Length+sizeof(UNICODE_STRING)*1,Num1-2;mov word ptr[ebp-0C8h],3Eh
lea edx,Message+sizeof(UNICODE_STRING)*1;lea edx,[ebp-0C8h]
mov HardErrorPointer+sizeof(PVOID)*1,edx;pwCaption;mov [ebp-0D8h],edx
;the third parameter
        mov HardErrorPointer+sizeof(PVOID)*2,MB_ICONASTERISK or MB_OK;uType;mov dword ptr[ebp-0D4h],40h
        lea edx,HardErrorPointer;lea     edx, [ebp-0DCh]
push offset x;where this function write the answer selected by the user (if the type passed to the
;next parameter, involves choosing an answer by the user)
push ebx;0 answers
push edx;a pointer to an array of parameters
push 3;the total number of parameters
push 00000011b;mask bits set which correspond to the
;parameters that are of type PUNICODE_STRING, and zeros - the other parameters
push STATUS_SERVICE_NOTIFICATION
call _imp__NtRaiseHardError@24
;--------------------------------------------------
;change the first parameter
lea edi,MessageBuffer
mov Message.Buffer+sizeof(UNICODE_STRING)*0,edi
mov Message.MaximumLength+sizeof(UNICODE_STRING)*0,Num3
mov Message._Length+sizeof(UNICODE_STRING)*0,Num3-2
lea edx,Message+sizeof(UNICODE_STRING)*0
mov HardErrorPointer+sizeof(PVOID)*0,edx;pwText
mov esi,offset MessageText2
mov ecx,Num3
rep movsb
lea edx,HardErrorPointer
mov eax,0B6h;ID NtRaiseHardError for WinXP
push offset x
push ebx
push edx
push 3
push 00000011b
push STATUS_SERVICE_NOTIFICATION
push offset a1
call dword ptr ds:[7FFE0300h];KiFastSystemCall
a1:
;--------------------------------------------------------
;change the first parameter
lea edi,MessageBuffer
mov Message.Buffer+sizeof(UNICODE_STRING)*0,edi
mov Message.MaximumLength+sizeof(UNICODE_STRING)*0,Num4
mov Message._Length+sizeof(UNICODE_STRING)*0,Num4-2
lea edx,Message+sizeof(UNICODE_STRING)*0
mov HardErrorPointer+sizeof(PVOID)*0,edx;pwText
mov esi,offset MessageText3
mov ecx,Num4
rep movsb
lea edx,HardErrorPointer
mov eax,0B6h;ID NtRaiseHardError for WinXP
push offset x
push ebx
push edx
push 3
push 00000011b
push STATUS_SERVICE_NOTIFICATION
push offset a2
push offset a2
mov edx,esp
db 0Fh,34h;sysenter
a2:
;--------------------------------------------------
lea edi,MessageBuffer
mov Message.Buffer+sizeof(UNICODE_STRING)*0,edi
mov Message.MaximumLength+sizeof(UNICODE_STRING)*0,Num2
mov Message._Length+sizeof(UNICODE_STRING)*0,Num2-2
lea edx,Message+sizeof(UNICODE_STRING)*0
mov HardErrorPointer+sizeof(PVOID)*0,edx;pwText
mov esi,offset MessageText1
mov ecx,Num2
rep movsb
lea edx,HardErrorPointer
mov eax,0B6h;ID NtRaiseHardError for WinXP
push offset x
push ebx
push edx
push 3
push 00000011b
push STATUS_SERVICE_NOTIFICATION
mov edx,esp
int 2Eh
leave
retn
ShowMessage endp
.data
MessageText dw 'N','t','R','a','i','s','e','H','a','r','d','E','r','r','o','r',0
Num equ $-MessageText
TitleText dw 'I','c','z','e','l','i','o','n',' ','T','u','t','o','r'
dw 'i','a','l',' ','#','2',':','M','e','s','s','a','g','e','B','o','x',0
Num1 equ $-TitleText
MessageText1 dw 'i','n','t',' ','2','E','h',0
Num2 equ $-MessageText1
MessageText2 dw 'K','i','F','a','s','t','S','y','s','t','e','m','C','a','l','l',0
Num3 equ $-MessageText2
MessageText3 dw 'S','y','s','e','n','t','e','r',0
Num4 equ $-MessageText3
x dd 0
Msg dd Msg1,Msg2,Msg3,Msg4,Msg5,Msg6,Msg7,Msg8,Msg9
Msg1 db 'MessageBoxA',0
Msg2 dw 'M','e','s','s','a','g','e','B','o','x','W',0
Msg3 db 'MessageBoxExA',0
Msg4 dw 'M','e','s','s','a','g','e','B','o','x','E','x','W',0
Msg5 db 'MessageBoxTimeoutA',0
Msg6 dw 'M','e','s','s','a','g','e','B','o','x','T','i','m','e','o','u','t','W',0
Msg7 dw 'S','o','f','t','M','o','d','a','l','M','e','s','s','a','g','e','B','o','x',0
Msg8 db 'MessageBoxIndirectA',0
Msg9 dw 'M','e','s','s','a','g','e','B','o','x','I','n','d','i','r','e','c','t','W',0
MsgCaption db "Iczelion Tutorial #2:MessageBox",0
_OK dw 'O','K',0
end start
« Last Edit: October 22, 2014, 04:05:20 PM by Mikl__ »

Magnum

  • Member
  • *****
  • Posts: 2308
Re: Beep without API
« Reply #13 on: October 22, 2014, 05:01:29 PM »
Great job Mikl_,  :t

I am very impressed.

How did you come up with the InitCommonControls to solve the problem ?

File size is comparable with invoke MessageBeep.
Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

Mikl__

  • Member
  • ****
  • Posts: 802
Re: Beep without API
« Reply #14 on: October 22, 2014, 05:24:38 PM »
Hi, Magnum!
file size can be greatly reduced if you
  • reduce the PE-header
  • alter imports section
  • make file align=8
  • merge code section with the section data