News:

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

Main Menu

Program runs in olly but not properly on it's own

Started by Don57, October 14, 2012, 06:11:14 AM

Previous topic - Next topic

Don57

Small app, a log scrubber, runs fine on it's first pass, but loads the process to 100% if run again because it fails to delete LogFile.txt.

In the Get_ELog_List proc if I put breakpoints after GetFileSize, ReadFile, CloseHandle, DeleteFile and run the program to the breakpoints everything works. If I put a single breakpoint after DeleteFile the first 3 calls give me Invalid_Handle_Value error and the DeleteFile returns a File_Not_Found error. It almost looks as if the code is too fast for the OS and I need to wait after every call to let the OS catch up.

qWord

Seems to "work" , but you may consider using Window's Event Log Functions (as Vortex suggest).
Also, your call to Check_Admin is missplaced -> move it to WM_CREATE or the startup code before WinMain.
MREAL macros - when you need floating point arithmetic while assembling!

Don57

I'll move the admin check. I must have missed vortex's post will give it a try.

The program works on the first pass but fails to delete the txt file it creates so it fails if you try to run it a second time. However it may be my version of windows.

Thanks.

qWord

OK, I found one problem: you do not wait for the created processes -> WaitForSingleObject(...,pi.hProcess,...). Also, you must close the Process handle.
You may also move the deletion-process into a seperate thread...
MREAL macros - when you need floating point arithmetic while assembling!

jj2007

The placement of the admin call in the main loop explains the high CPU usage. For every tiny movement of the mouse, that proc gets called a hundred times.

Re WaitForSingleObject, here is an excerpt from MasmBasic's Launch macro - may save you some typing ;-)

  xor ecx, ecx ; using ecx as NULL saves some bytes
  invoke CreateProcess, ecx, ; no pathname
  cmdline, ; the only bit that REALLY counts...!
  ecx, ecx, sat.bInheritHandle, ; lpProcessAttributes, lpThreadAttributes, bInheritHandles
  edx, ecx, ecx, ; dwCreationFlags, lpEnvironment, lpCurrentDirectory
  ebx, ; read from STARTUPINFO (ebx=addr sinfo)
  addr pinfo ; write to PROCESS_INFORMATION
  xor ebx, ebx ; flag fail
  .if eax
mov ebx, pinfo.hProcess ; wow, we got a handle! Actually, we got two...
.if ebx
invoke WaitForSingleObject, ebx, edi ; specify milliseconds here
push ecx ; create a stack slot for the exit code
invoke GetExitCodeProcess, ebx, esp ; esp=addr ExCode
invoke CloseHandle, ebx
invoke CloseHandle, pinfo.hThread
pop edx ; retrieve exit code from the stack, return in edx
.endif
  .endif

Don57

Changed the location of the Admin Check, added a wait WaitForSingleObject and CloseHandle. Works better can't find any errors and the process appears to wait. Not sure if the call WaitForSingleObject is structured properly it seemed too easy. Included a picture of my Admin logs after a morning test new boards.

TouEnMasm


The check for admin don't work:
Quote
Msdn sample
BOOL IsUserAdmin(VOID)
/*++
Routine Description: This routine returns TRUE if the caller's process
is a member of the Administrators local group. Caller is NOT expected
to be impersonating anyone and is expected to be able to open its own
process and process token.
Arguments: None.
Return Value:
   TRUE - Caller has Administrators local group.
   FALSE - Caller does not have Administrators local group. --
*/
{
BOOL b;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
PSID AdministratorsGroup;
b = AllocateAndInitializeSid(
    &NtAuthority,
    2,
    SECURITY_BUILTIN_DOMAIN_RID,
    DOMAIN_ALIAS_RID_ADMINS,
    0, 0, 0, 0, 0, 0,
    &AdministratorsGroup);
if(b)
{
    if (!CheckTokenMembership( NULL, AdministratorsGroup, &b))
    {
         b = FALSE;
    }
    FreeSid(AdministratorsGroup);
}

return(b);
}

Fa is a musical note to play with CL

Vortex

IsUserAnAdmin function :

.386
.model flat,stdcall
option casemap:none

include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     \masm32\include\user32.inc
include     \masm32\include\shell32.inc

includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\user32.lib
includelib  \masm32\lib\shell32.lib

.data

text1       db 'The user is not a member of the Administrators group',0
text2       db 'The user is a member of the Administrators group',0
capt        db 'IsUserAnAdmin',0

array       dd text1,text2

.code

start:

    invoke  IsUserAnAdmin

    lea     edx,[array+4*eax]

    invoke  MessageBox,0,DWORD PTR [edx],ADDR capt,MB_OK
   
    invoke  ExitProcess,0

END start

jj2007

Works perfectly, Erol :t
I wonder if it's still available on Win7 & Win8, though ::)

Don57

The Admin check appears to work fine on windows 7, but I'll try thhe ToutEnMasm's code and see what happens.


I want to thank everbody for all their help. Sometimes I get so wrapped up in solving the problems in the code I forget to.
Thank You.

Don57

Checked on the Admin. In windows, at least on my own PC, I  log in as Administrator but I still have to run the program as an Administrator from the right button menu. The check in the program as it exists checks to make sure that I am running it this elevated state. I believe that ToutEnMasm and Vortex's code check the initial log on conditions to make sure the user is logged in as an administrator. Both administrator procs are probably necessary for the program to function properly. The first to check that the user is indeed an Administrator and the second to check that the program is being run in an elevated (administrator) state.

TouEnMasm


Here the translated code from MSDN,work well on my XP3

.data
;SECURITY_NT_AUTHORITY TEXTEQU <0,0,0,0,0,5>
NtAuthority SID_IDENTIFIER_AUTHORITY <>
AdministratorsGroup dd 0
.code
Check_Admin proc                   
    LOCAL Is_Admin:DWORD
mov eax,offset NtAuthority.Value
mov byte ptr [eax+5],5 ;SECURITY_NT_AUTHORITY TEXTEQU <0,0,0,0,0,5>
invoke AllocateAndInitializeSid,addr NtAuthority,2,SECURITY_BUILTIN_DOMAIN_RID,\
DOMAIN_ALIAS_RID_ADMINS,0, 0, 0, 0, 0, 0,addr AdministratorsGroup
.if eax != 0
mov Is_Admin,eax
invoke CheckTokenMembership,NULL,AdministratorsGroup,addr Is_Admin
.if eax == 0
mov Is_Admin,0
.endif

.endif
mov eax,Is_Admin
      ret

Check_Admin endp

Fa is a musical note to play with CL

Vortex

Hi Jochen,

Here is what I found :

QuoteRemarks
This function is a wrapper for CheckTokenMembership. It is recommended to call that function directly to determine Administrator group status rather than calling IsUserAnAdmin.

Requirements

Minimum supported client
Windows XP

Minimum supported server
Windows Server 2003

End of client support
Windows Vista

End of server support
Windows Server 2008

http://msdn.microsoft.com/en-us/library/windows/desktop/bb776463(v=vs.85).aspx

Don57

I tried ToutEnMasm's code snippet, it runs fine. There is one declaration in the data statement that I don't understand.

NtAuthority SID_IDENTIFIER_AUTHORITY <>


Thanks. :greenclp:

TouEnMasm


Quote
.const
SID_IDENTIFIER_AUTHORITY   STRUCT   DEFALIGNMASM
   Value BYTE 6 dup (?)
SID_IDENTIFIER_AUTHORITY      ENDS
.data
NtAuthority SID_IDENTIFIER_AUTHORITY <>    ;name of the struct in data

c++ initialyse  the value of each byte with that <0,0,0,0,0,5>
Masm don't accept, so init is made on data with a pointer on NtAuthority.Value + n BYTE



Fa is a musical note to play with CL