Need help converting 'trainer' to PureBasic

Just starting out? Need help? Post your questions and find answers here.
gkaizer
User
User
Posts: 40
Joined: Fri Oct 31, 2003 2:57 pm
Location: Italy

Post by gkaizer »

ok, i've ported a little example of WriteConsole from VB

Code: Select all

#FOREGROUND_BLUE = $1
#FOREGROUND_GREEN = $2
#FOREGROUND_RED = $4
#BACKGROUND_BLUE = $10
#BACKGROUND_GREEN = $20
#BACKGROUND_RED = $40
#BACKGROUND_INTENSITY = $80
#BACKGROUND_SEARCH = $20
#FOREGROUND_INTENSITY = $8
#FOREGROUND_SEARCH = ($10)
#ENABLE_LINE_INPUT = $2
#ENABLE_ECHO_INPUT = $4
#ENABLE_MOUSE_INPUT = $10
#ENABLE_PROCESSED_INPUT = $1
#ENABLE_WINDOW_INPUT = $8
#ENABLE_PROCESSED_OUTPUT = $1
#ENABLE_WRAP_AT_EOL_OUTPUT = $2
#STD_OUTPUT_HANDLE = -11
#STD_INPUT_HANDLE = -10
#STD_ERROR_HANDLE = -12
#INVALID_HANDLE_VALUE = -1


Global hConsoleOut.l, hConsoleIn.l
If AllocConsole_()
  hConsoleOut = GetStdHandle_ (#STD_OUTPUT_HANDLE)
  If hConsoleOut = #INVALID_HANDLE_VALUE 
    MessageRequester("?","Unable To get STDOUT",1)
  EndIf
  hConsoleIn = GetStdHandle_(#STD_INPUT_HANDLE)
  If hConsoleIn = #INVALID_HANDLE_VALUE 
    MessageRequester("?","Unable To get STDIN",1) 
  EndIf
Else
  MessageRequester("?","Couldn't allocate console",1)
EndIf

SetConsoleTitle_("Test const void *")
SetConsoleTextAttribute_ (hConsoleOut, #FOREGROUND_RED | #FOREGROUND_GREEN | #FOREGROUND_INTENSITY | #BACKGROUND_BLUE)  

Procedure ConsoleWritel(sInput.s)
  cWritten.l
  WriteConsole_(hConsoleOut, sInput, Len(sInput), cWritten, #NULL) 
EndProcedure

Procedure.s ConsoleRead()
  ZeroPos.l
  ConsoleReadLine.s = "0000000000"
  ReadConsole_ (hConsoleIn, ConsoleReadLine, Len(ConsoleReadLine), #NULL, #NULL)
  ZeroPos = FindString(ConsoleReadLine, Chr(0),1)
  If ZeroPos > 0 
    ConsoleReadLine = Left(ConsoleReadLine, ZeroPos - 3)
    ProcedureReturn ConsoleReadLine
  EndIf
EndProcedure

ConsoleWritel("Please enter your name: ")

MessageRequester(ConsoleRead(),"Your Name:",1)
and as WriteConsole has that kind of argument (const void *), i've tested in PureBasic, and works well, no problem...

Therefore I think the ByVal problem is not-existing :)

The reason why the code submitted by PB does't work is not imputable to how PB deals with API's, but is in the code...

Anyway i'll find other examples and try again :)
byez
--:: Gkaizer ::--
Using PB 3.92 on WinXP SP2 and 3.91 on Mandrake Linux 10.0
User avatar
Rings
Moderator
Moderator
Posts: 1435
Joined: Sat Apr 26, 2003 1:11 am

Post by Rings »

after investigate some minutes in this problem (i tested with VB and Pure twice) the solution is total easy and have nothing to do with ByVal :


use a allocated memory for the mbi structure , so that it is 16 byte aligned to use with the api:

Code: Select all

.
.
.
adr=AllocateMemory(1,28)
*mbi=adr
While lpMem < si\lpMaximumApplicationAddress 
    ret = VirtualQueryEx_(hProcess, lpMem, adr,lLenMBI ) 
.
.
and for to search the string remember that often Anis-Widestrings are used (2 byte per character, second byte often NULL ) .
SPAMINATOR NR.1
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> the solution is total easy and have nothing to do with ByVal

I tried using your code in the example but it still doesn't work... what
do you mean by "the solution is total easy" ? :(

> and for to search the string remember that often Anis-Widestrings are
> used (2 byte per character, second byte often NULL ).

Perhaps that's the problem, because in the Visual Basic example the
strings are converted to Unicode on NT-based machines; BUT if I try
the code (and your snippet) on Win 98 it also doesn't work, so... :(
User avatar
Rings
Moderator
Moderator
Posts: 1435
Joined: Sat Apr 26, 2003 1:11 am

Post by Rings »

PB wrote:I tried using your code in the example but it still doesn't work... whatdo you mean by "the solution is total easy" ?
The problem while VirtualQueryEx fails is the align of the structure mbi !!!
if you use memory it works still fine (while memory is 16 byte aligned)

for the problem with Widestrings and Win89 : ignore those crappy os like i do :)

btw, my code works for the trainer .
SPAMINATOR NR.1
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> btw, my code works for the trainer

Ohhhhhhhhhh! :) Okay, since I can't get it working, can you please
post a working example for us? Please? :)
User avatar
Rings
Moderator
Moderator
Posts: 1435
Joined: Sat Apr 26, 2003 1:11 am

Post by Rings »

Code: Select all

;
; simple Trainer, ported from vb to Pure
; search in a other process's memory for a keyword (here wideansi string)
; and replace that with our own
; 
; another hack brought to you by Codeguru 
; 2003 Siegfried Rings
;

#PROCESS_VM_READ = $10 
#PROCESS_VM_WRITE = $20 
#PROCESS_VM_OPERATION = $8 
#PROCESS_QUERY_INFORMATION = $400 
#PROCESS_READ_WRITE_QUERY = #PROCESS_VM_READ|#PROCESS_VM_WRITE|#PROCESS_VM_OPERATION|#PROCESS_QUERY_INFORMATION 
#PROCESS_ALL_ACCESS= $1F0FFF

#MEM_PRIVATE = $20000 
#MEM_COMMIT = $1000 

Global ProcessID.l 

Procedure.l RunProgramEx(Filename.s,Parameter.s,Directory.s,ShowFlag.l) 
  Info.STARTUPINFO : Info\cb=SizeOf(STARTUPINFO) : Info\dwFlags=1 
  Info\wShowWindow=ShowFlag : ProcessInfo.PROCESS_INFORMATION 
  ProcessPriority=#NORMAL_PRIORITY_CLASS 
  If CreateProcess_(@Filename,@Parameter,0,0,0,ProcessPriority,0,@Directory,@Info,@ProcessInfo) 
    ProcessID.l=ProcessInfo\dwProcessId 
    Repeat 
      win=FindWindow_(0,0) 
      While win<>0 
        GetWindowThreadProcessId_(win,@pid.l) 
        If pid=ProcessID : WinHandle=win : Break : EndIf 
        win=GetWindow_(win,#GW_HWNDNEXT) 
      Wend 
    Until WinHandle 
  EndIf 
  ProcedureReturn WinHandle 
EndProcedure 

Procedure CompareMemorybuffers(Bufferadress1,Bufferadress2,Len1,len2)
 L=0 
 L2=len1-Len2  -1
 Repeat
  B2.b=PeekB(Bufferadress2)
  B1.b=PeekB(Bufferadress1+L)
  If B1=B2
   t=0
   For L3=1 To Len2-1
    B2.b=PeekB(Bufferadress2+L3)
    B1.b=PeekB(Bufferadress1+L+L3)
     If B2=B1
      If B2<>0 
       ;Debug "Should="+Chr(B2) +"  is= "+Chr(B1)
      EndIf
      t+1 
     Else
      Break
     EndIf
   Next L3
   If t=len2 -1
    ProcedureReturn l
   EndIf      
  EndIf
  L+1
 Until L=L2
EndProcedure

sSearchString.s = "Back" 
aSearchString.s =Space(2*Len(sSearchString.s))
MultiByteToWideChar_ ( #CP_ACP, 0,@sSearchString.s ,Len(sSearchString.s ),@aSearchString.s ,Len(aSearchString.s ) )

sReplaceString.s = "Pure" 
aReplaceString.s =Space(2*Len(sReplaceString.s))
MultiByteToWideChar_ ( #CP_ACP, 0,@sReplaceString.s ,Len(sReplaceString.s ),@aReplaceString.s ,Len(aReplaceString.s ) )


si.SYSTEM_INFO 
hWin=RunProgramEx("c:\winnt\system32\calc.exe","","c:\winnt\system32\",#SW_SHOW) 
;ProcessID=Val(InputRequester("Info","input PID",Str(ProcessID)))
;Debug "PID="+Str(ProcessID) ;that is the processhandle !!!
; better open with full access to close it later
hProcess = OpenProcess_(#PROCESS_ALL_ACCESS,0,ProcessID) 
;Debug hProcess

lLenMBI = SizeOf(MEMORY_BASIC_INFORMATION ) 
;Debug "ilENMBI="+Str(lLenmbi)
GetSystemInfo_(si) 
lpMem = si\lpMinimumApplicationAddress 
;Debug lpmem 
;Debug si\lpMaximumApplicationAddress 
*mbi.MEMORY_BASIC_INFORMATION 
adr=AllocateMemory(1,28)
*mbi=adr
While lpMem < si\lpMaximumApplicationAddress 
    ret = VirtualQueryEx_(hProcess, lpMem, adr,lLenMBI ) ; *** ALWAYS RETURNS 0 *** 
    ;ret = VirtualQueryEx_(hProcess, lpMem, mbi2,lLenMBI ) ; *** ALWAYS RETURNS 0 *** 
    ;Debug "Ret="+Str(ret)
    If ret = lLenMBI 
        If ((*mbi\lType = #MEM_PRIVATE) And (*mbi\State = #MEM_COMMIT)) 
            If *mbi\RegionSize > 0 
               sBuffer = AllocateMemory(0,*mbi\RegionSize) 
               Res=ReadProcessMemory_(hProcess, *mbi\BaseAddress, sBuffer, *mbi\RegionSize, @lWritten) 
               ;Remember that most Programs use Ansi-Widestrings, 
               If lWritten>0 And res>0 
                l=CompareMemorybuffers(sBuffer,@aSearchString.s ,*mbi\RegionSize,Len(sSearchstring.s) )
                If L>0
                 Debug "found at Pos. "+Str(l)+ "  : "+PeekS(sBuffer+L,1) +PeekS(sBuffer+L+2,1)+PeekS(sBuffer+L+4,1)+PeekS(sBuffer+L+6,1)
                 CalcAddress = *mbi\BaseAddress + l
                 result=WriteProcessMemory_(hProcess, CalcAddress , @aReplaceString.s, Len(sReplaceString.s)*2, @lWritten) 
                EndIf
               EndIf
               FreeMemory(0)
            EndIf  
        EndIf 
        lpMem = *mbi\BaseAddress + *mbi\RegionSize 
    Else 
      Break 
    EndIf 
Wend 

If hProcess
; TerminateProcess_(hprocess,0) 
 CloseHandle_(hProcess) 
EndIf
FreeMemory(1)
End
SPAMINATOR NR.1
User avatar
Rings
Moderator
Moderator
Posts: 1435
Joined: Sat Apr 26, 2003 1:11 am

Post by Rings »

did the example work PB ?
SPAMINATOR NR.1
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> did the example work PB ?

Yep, for Windows 2000 -- but not on Windows 98 SE (for me). Can
anyone else with 98 confirm? (And yes, I changed the path to the
correct location of calc).

No wonder I couldn't get it working with Windows 2000 before: your
example has a lot more code in it (converting to Unicode, etc). ;)
User avatar
Rings
Moderator
Moderator
Posts: 1435
Joined: Sat Apr 26, 2003 1:11 am

Post by Rings »

PB wrote:> did the example work PB ?

Yep, for Windows 2000 -- but not on Windows 98 SE (for me). Can
anyone else with 98 confirm? (And yes, I changed the path to the
correct location of calc).

No wonder I couldn't get it working with Windows 2000 before: your
example has a lot more code in it (converting to Unicode, etc). ;)
i do not have a working win89 anymore but as i remember , you can test under win89 without unicodestrings directly (Change the search in Memory-routines) .
SPAMINATOR NR.1
Henrik
Enthusiast
Enthusiast
Posts: 404
Joined: Sat Apr 26, 2003 5:08 pm
Location: Denmark

Post by Henrik »

@PB & Rings
I haven't read the whole tread, so i'm sorry if i'm totally off here.
On my win98 Se, the ReadProcessMemory part and peeking for strings seems to work okay.
But WriteProcessMemory failes ~I take it that it is suppose change B to P or Back To Pure~ ?

Best Regards
Henrik.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> > did the example work PB ?
>
> Yep, for Windows 2000 -- but not on Windows 98 SE

Okay, I worked out what I was doing wrong -- I was converting the
search/replace strings to Unicode on 98, when you're only supposed
to do that on NT-based Windows. So, here's my/your amended code,
which I can confirm works great on 98, ME, 2000, and XP (not on 95
or NT because this example replaces "Backspace" in Calc, and Calc
on those versions is called "Back").

Again, thank you, Rings, for helping port this to PureBasic! :D

[Edited 20 Jan 2007 to work with PureBasic v4.02]

Code: Select all

; simple Trainer, ported from vb to Pure
; search in a other process's memory for a keyword (here wideansi string)
; and replace that with our own

; another hack brought to you by Codeguru
; 2003 Siegfried Rings

; Modified a bit by PB to run on 98/ME as well as 2000/XP.  :)

Global ProcessID.l

Procedure.l RunProgramEx(Filename.s,Parameter.s,Directory.s,ShowFlag.l)
  If Left(Parameter,1)<>" " : Parameter=" "+Parameter : EndIf
  Info.STARTUPINFO : Info\cb=SizeOf(STARTUPINFO) : Info\dwFlags=1
  Info\wShowWindow=ShowFlag : ProcessInfo.PROCESS_INFORMATION
  ProcessPriority=#NORMAL_PRIORITY_CLASS
  If CreateProcess_(@Filename,@Parameter,0,0,0,ProcessPriority,0,@Directory,@Info,@ProcessInfo)
    ProcessID.l=ProcessInfo\dwProcessId
    Repeat
      win=FindWindow_(0,0)
      While win<>0
        GetWindowThreadProcessId_(win,@pid.l)
        If pid=ProcessID : WinHandle=win : Break : EndIf
        win=GetWindow_(win,#GW_HWNDNEXT)
      Wend
    Until WinHandle
  EndIf
  ProcedureReturn WinHandle
EndProcedure

Procedure CompareMemorybuffers(Bufferadress1,Bufferadress2,Len1,len2)
L=0
L2=len1-Len2 -1
Repeat
  B2.b=PeekB(Bufferadress2)
  B1.b=PeekB(Bufferadress1+L)
  If B1=B2
   t=0
   For L3=1 To Len2-1
    B2.b=PeekB(Bufferadress2+L3)
    B1.b=PeekB(Bufferadress1+L+L3)
     If B2=B1
      t+1
     Else
      Break
     EndIf
   Next L3
   If t=len2 -1
    ProcedureReturn l
   EndIf
  EndIf
  L+1
Until L=L2
EndProcedure

sSearchString.s = "Backspace"
sReplaceString.s = "PurePower"

si.SYSTEM_INFO
If OSVersion()>#PB_OS_Windows_ME ; 2000 and XP.
  If OSVersion()=#PB_OS_Windows_2000
    hWin=RunProgramEx("c:\winnt\system32\calc.exe","","c:\winnt\system32\",#SW_SHOW)
  Else ; XP.
    hWin=RunProgramEx("c:\windows\system32\calc.exe","","c:\windows\system32\",#SW_SHOW)
  EndIf
  aSearchString.s=Space(2*Len(sSearchString.s))
  MultiByteToWideChar_(#CP_ACP,0,@sSearchString.s,Len(sSearchString.s),@aSearchString.s,Len(aSearchString.s))
  aReplaceString.s=Space(2*Len(sReplaceString.s))
  MultiByteToWideChar_(#CP_ACP,0,@sReplaceString.s,Len(sReplaceString.s),@aReplaceString.s,Len(aReplaceString.s))
Else ; Windows 98/ME.
  hWin=RunProgramEx("c:\windows\calc.exe","","c:\windows\",#SW_SHOW)
EndIf
hProcess = OpenProcess_(#PROCESS_ALL_ACCESS,0,ProcessID)
lLenMBI = SizeOf(MEMORY_BASIC_INFORMATION )
GetSystemInfo_(si)
lpMem = si\lpMinimumApplicationAddress
*mbi.MEMORY_BASIC_INFORMATION
adr=AllocateMemory(28)
*mbi=adr
While lpMem < si\lpMaximumApplicationAddress
    ret = VirtualQueryEx_(hProcess, lpMem, adr,lLenMBI )
    If ret = lLenMBI
        If ((*mbi\lType = #MEM_PRIVATE) And (*mbi\State = #MEM_COMMIT))
            If *mbi\RegionSize > 0
               sBuffer = AllocateMemory(*mbi\RegionSize)
               Res=ReadProcessMemory_(hProcess, *mbi\BaseAddress, sBuffer, *mbi\RegionSize, @lWritten)
               If lWritten>0 And res>0
                If OSVersion()>#PB_OS_Windows_ME ; 2000 and XP.
                  l=CompareMemorybuffers(sBuffer,@aSearchString.s ,*mbi\RegionSize,Len(sSearchstring.s) )
                Else ; 98/ME.
                  l=CompareMemorybuffers(sBuffer,@sSearchString.s ,*mbi\RegionSize,Len(sSearchstring.s) )
                EndIf
                If l>0
                 ;Debug "found at Pos. "+Str(l)+ "  : "+PeekS(sBuffer+L,1) +PeekS(sBuffer+L+2,1)+PeekS(sBuffer+L+4,1)+PeekS(sBuffer+L+6,1)
                 CalcAddress = *mbi\BaseAddress + l
                 If OSVersion()>#PB_OS_Windows_ME ; 2000 and XP.
                  result=WriteProcessMemory_(hProcess, CalcAddress , @aReplaceString.s, Len(sReplaceString.s)*2, @lWritten)
                 Else ; 98/ME.
                  result=WriteProcessMemory_(hProcess, CalcAddress , @sReplaceString.s, Len(sReplaceString.s)*2, @lWritten)
                 EndIf
                 InvalidateRect_(hWin,0,1) ; Redraw Calc to show the change.
                EndIf
               EndIf
               FreeMemory(sBuffer)
            EndIf
        EndIf
        lpMem = *mbi\BaseAddress + *mbi\RegionSize
    Else
      Break
    EndIf
Wend

If hProcess
  CloseHandle_(hProcess)
EndIf
FreeMemory(adr)
Post Reply