How to retrieve the size of a procedure?
Re: How to retrieve the size of a procedure?
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.
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.
- Kaeru Gaman
- Addict
- Posts: 4826
- Joined: Sun Mar 19, 2006 1:57 pm
- Location: Germany
Re: How to retrieve the size of a procedure?
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>
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.
Re: How to retrieve the size of a procedure?
@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.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>
Regarding definition of 'bazaar', I believe srod meant 'bazarre' which means unusual or exotic.

Re: How to retrieve the size of a procedure?
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.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>
Doh!!! That was it! Thanks Demivec.Demivec wrote:@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() ).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?

I may look like a mule, but I'm not a complete ass.
- Kaeru Gaman
- Addict
- Posts: 4826
- Joined: Sun Mar 19, 2006 1:57 pm
- Location: Germany
Re: How to retrieve the size of a procedure?
that is written "bizarre", I mentioned this vocable...Demivec wrote:Regarding definition of 'bazaar', I believe srod meant 'bazarre' which means unusual or exotic.
oh... and have a nice day.
Re: How to retrieve the size of a procedure?
I did indeed mean bizarre! 

I may look like a mule, but I'm not a complete ass.
Re: How to retrieve the size of a procedure?
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!
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!
Re: How to retrieve the size of a procedure?
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.
Re: How to retrieve the size of a procedure?
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.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.

poor English...
PureBasic & Delphi & VBA
PureBasic & Delphi & VBA
Re: How to retrieve the size of a procedure?
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:

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
-
- Enthusiast
- Posts: 334
- Joined: Mon Feb 04, 2013 5:28 pm
Re: How to retrieve the size of a procedure?
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).
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).
Re: How to retrieve the size of a procedure?
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:
Becomes (/commented) ...
Compiles to ...
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

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!

Code: Select all
Procedure Test()
!Test_Begin:
Protected var1.l, var2.l
var1 = 3: var2 = 2
var1 = var1 + var2
ProcedureReturn var1
!Test_End:
EndProcedure
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
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

Re: How to retrieve the size of a procedure?
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.
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.
Re: How to retrieve the size of a procedure?
Whoa, how presumptive! ...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.


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.
Re: How to retrieve the size of a procedure?
I didn't say anything about malware and presumed nothing.Keya wrote:Whoa, how presumptive! ...When in doubt presume the programmer is writing malware!?!?!?
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.