How to retrieve the size of a procedure?

Just starting out? Need help? Post your questions and find answers here.
Thorium
Addict
Addict
Posts: 1305
Joined: Sat Aug 15, 2009 6:59 pm

Re: How to retrieve the size of a procedure?

Post by Thorium »

If you copy code into another process you have to be very carefull what you copy anyway.
If you copy code that calls other procedures in you program it will crash the target process. Most PB commands are compiled as calls into libs. So most of them will just crash the target process. If it uses global variables, it will crash the process. If it uses API's not importet by the target process it will crash it.

But you can avoit all this by just injecting a dll into the target process. Use the board search and search for "dll injection". This is the standart way to get additional code into another process. And it's the most stable way.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Re: How to retrieve the size of a procedure?

Post by Kaeru Gaman »

I also thought about the starting adress of the next procedure...
but is it guaranteed that the sequency of procedures in the exe is the same as in the code?

<offtopic>
bazaar = unmotivated expensive?
... you did
not mean 'bizarre', I think ...?
</offtopic>
oh... and have a nice day.
User avatar
Demivec
Addict
Addict
Posts: 4260
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: How to retrieve the size of a procedure?

Post by Demivec »

Kaeru Gaman wrote:I also thought about the starting adress of the next procedure...
but is it guaranteed that the sequency of procedures in the exe is the same as in the code?

<offtopic>
bazaar = unmotivated expensive?
... you did
not mean 'bizarre', I think ...?
</offtopic>
@Kaeru: regarding sequence of procedures, I don't think it is pre-determined. For instance, it may depend on the order in which they are called.

Regarding definition of 'bazaar', I believe srod meant 'bazarre' which means unusual or exotic. :)
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: How to retrieve the size of a procedure?

Post by srod »

Kaeru Gaman wrote:I also thought about the starting adress of the next procedure...
but is it guaranteed that the sequency of procedures in the exe is the same as in the code?

<offtopic>
bazaar = unmotivated expensive?
... you did
not mean 'bizarre', I think ...?
</offtopic>
For each procedure referenced, the generated ASM seemes to invoke the macros in alphabetical order so providing the 'dummy' procedure immediately follows the one of interest in alphabetic order you should be fine.
Demivec wrote:
srod wrote:I think that @zum1() - @test1() in the example above should give a result which is certainly no smaller than the required result. Quite why I am getting some bazaar results escapes me at the moment? Alignment perhaps?
@srod: regarding the possible reasons for your bazaar results, your examples include the debugger code woven around your desired code. Your example shows 85 bytes for me (with Win XP) with debugger but only 17 without debugger (using MessageRequester() ).
Doh!!! That was it! Thanks Demivec. :)
I may look like a mule, but I'm not a complete ass.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Re: How to retrieve the size of a procedure?

Post by Kaeru Gaman »

Demivec wrote:Regarding definition of 'bazaar', I believe srod meant 'bazarre' which means unusual or exotic. :)
that is written "bizarre", I mentioned this vocable...
oh... and have a nice day.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: How to retrieve the size of a procedure?

Post by srod »

I did indeed mean bizarre! :)
I may look like a mule, but I'm not a complete ass.
Hi-Toro
Enthusiast
Enthusiast
Posts: 269
Joined: Sat Apr 26, 2003 3:23 pm

Re: How to retrieve the size of a procedure?

Post by Hi-Toro »

Something like this might be of use, though I struggled to convert it to Blitz or PB, and it's only relevant to x86:

http://www.devmaster.net/forums/showthread.php?t=2311

The idea is that you detect the byte-level x86 instructions by reading from the start of the function in memory until the byte signifying the end of the function.

I couldn't get it to work, but there are many nested C-style If {...} loops that I probably screwed up on!
James Boyd
http://www.hi-toro.com/
Death to the Pixies!
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: How to retrieve the size of a procedure?

Post by srod »

Yes that is always another option; but in the case of PB code you will probably need to look for a RET command. This means interpreting all previous bytes to account for variable length x86 instructions etc. A bit too much work in my opinion. :)
I may look like a mule, but I'm not a complete ass.
User avatar
leonhardt
Enthusiast
Enthusiast
Posts: 220
Joined: Wed Dec 23, 2009 3:26 pm

Re: How to retrieve the size of a procedure?

Post by leonhardt »

Thorium wrote:If you copy code into another process you have to be very carefull what you copy anyway.
If you copy code that calls other procedures in you program it will crash the target process. Most PB commands are compiled as calls into libs. So most of them will just crash the target process. If it uses global variables, it will crash the process. If it uses API's not importet by the target process it will crash it.

But you can avoit all this by just injecting a dll into the target process. Use the board search and search for "dll injection". This is the standart way to get additional code into another process. And it's the most stable way.
Of course ,I've mentioned what you had said in my code comments,any PB command or string can't be used in the remote thread function,but my code should work because my thread function is "pure" enough,and it did work,sometimes it's handy to inject a thread in that way rather than use a dll. :mrgreen:
poor English...

PureBasic & Delphi & VBA
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: How to retrieve the size of a procedure?

Post by Keya »

It appears using a second procedure below the target procedure is NOT RELIABLE for detecting target procedure size. And the ?Label2-?Label1 example provided earlier in this thread doesn't compile because you can't directly reference labels in procedures from PB code outside the procedure ... but you can with !direct asm :)

Example:

Code: Select all

DisableDebugger

Procedure Test()
!Test_Begin:
  ;procedure code here
  ! nop
  ! nop
  ! nop
!Test_End:
EndProcedure

Test()  ;reference the procedure simply so its included in the compile

Define procsize.l
! mov eax, Test_End
! sub eax, Test_Begin
! mov [v_procsize], eax
MessageRequester("Procedure Size", Str(procsize))  ;should be 3 as the Test() proc is just 3 nops
DontTalkToMe
Enthusiast
Enthusiast
Posts: 334
Joined: Mon Feb 04, 2013 5:28 pm

Re: How to retrieve the size of a procedure?

Post by DontTalkToMe »

Another way, sort of, if it's not possible or desirable to modify the target procedure by adding the two labels.

http://www.purebasic.fr/english/viewtop ... 77#p483177

also this should catch the code before and after the main procedure body (if that's something you want, to get the whole procedure size).
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: How to retrieve the size of a procedure?

Post by Keya »

the problem with your method is that, apart from requiring a full disassembler, is that the disassembler itself that PB uses (Udis86) is old and poor from results its given me and ive seen it trip up on some very simple opcodes, so it's not really useful for anything that isn't in-house i don't think :( i think the Udis86 libs that come with PB havent been updated in a while so it might be better now (it was updated 2014 and supports SSE 4.2, AVX etc)

and yes you're right the problem with my method is it misses the small parts before and after the main body, I shouldve clarified that! :) You can see here for example:

Code: Select all

Procedure Test()
 !Test_Begin:
  Protected var1.l, var2.l
  var1 = 3: var2 = 2
  var1 = var1 + var2
  ProcedureReturn var1
!Test_End:
EndProcedure
Becomes (/commented) ...

Code: Select all

; Procedure Test()
_Procedure0:
  PUSH   ebx
  PS0=16
  XOR    eax,eax
  PUSH   eax
  PUSH   eax
; !Test_Begin:
Test_Begin:                            ;<--------------
; Protected var1.l, var2.l
; var1 = 3: var2 = 2
  MOV    dword [esp],3
  MOV    dword [esp+4],2
; var1 = var1 + var2
  MOV    ebx,dword [esp]
  ADD    ebx,dword [esp+4]
  MOV    dword [esp],ebx
; ProcedureReturn var1
  MOV    eax,dword [esp]
  JMP   _EndProcedure1
; !Test_End:
p.v_var1 equ esp+0
p.v_var2 equ esp+4
Test_End:                              ;<--------------
; EndProcedure
_EndProcedureZero1:
  XOR    eax,eax
_EndProcedure1:
  ADD    esp,8
  POP    ebx
  RET
Compiles to ...

Code: Select all

53                       push ebx
31C0                     xor eax, eax
50                       push eax
50                       push eax
Test_Begin:
 C70424 03000000          mov dword ptr [esp], 3
 C74424 04 02000000       mov dword ptr [esp+4], 2
 8B1C24                   mov ebx, dword ptr [esp]
 035C24 04                add ebx, dword ptr [esp+4]
 891C24                   mov dword ptr [esp], ebx
 8B0424                   mov eax, dword ptr [esp]
 EB 02                    jmp short PureBasi.004010EA
Test_End:
31C0                     xor eax, eax
83C4 08                  add esp, 8
5B                       pop ebx
C3                       retn
Although we can still get the very START by simply refering to @Procedure() instead of the first label (?Test_Begin) :) that just leaves the trailer part missing then
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: How to retrieve the size of a procedure?

Post by Mistrel »

What would be a viable use case for this? Reading a procedure as memory and writing it to a remote process for execution? Without either carefully inspecting the compiled code before injection or writing the ASM yourself, I can't even begin to imagine the potential for corruption and illegal access this would cause.

The only safe way to do this would be DLL injection or to write the ASM yourself to ensure that the function doesn't try to access an address from the wrong memory space.
User avatar
Keya
Addict
Addict
Posts: 1890
Joined: Thu Jun 04, 2015 7:10 am

Re: How to retrieve the size of a procedure?

Post by Keya »

What would be a viable use case for this? Reading a procedure as memory and writing it to a remote process for execution? Without either carefully inspecting the compiled code before injection or writing the ASM yourself, I can't even begin to imagine the potential for corruption and illegal access this would cause.
Whoa, how presumptive! ... :) When in doubt presume the programmer is writing malware!?!?!? :(

I can't speak for the others in this thread but I'm simply doing a checksum of my routine to detect modification such as a cracker. (The checksum has to be done after the image is loaded due to address relocations - i just do it at app startup, but any modifications made thereafter such as a breakpoint are easily detected). No memory writing or injection or remote processes (or other nasty things going through your mind!) involved.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: How to retrieve the size of a procedure?

Post by Mistrel »

Keya wrote:Whoa, how presumptive! ... :) When in doubt presume the programmer is writing malware!?!?!? :(
I didn't say anything about malware and presumed nothing.

Performing a checksum on the size of a procedure wouldn't work as you can't inject additional ASM into a compiled image without offsetting hard-coded pointers. Generally these types of changes are either NOPs or replacing ASM with something else but without changing the effective size.

You would have to checksum the instructions themselves to detect something like this.

I rarely work with ASM but I don't believe randomized relocation affects the ASM as hard-coded pointers are generally relative offsets. The actual pointer being resolved may be different but the ASM itself wouldn't be.
Post Reply