Page 2 of 3
Re: How to retrieve the size of a procedure?
Posted: Thu Jan 14, 2010 5:04 pm
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.
Re: How to retrieve the size of a procedure?
Posted: Thu Jan 14, 2010 5:15 pm
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>
Re: How to retrieve the size of a procedure?
Posted: Thu Jan 14, 2010 5:58 pm
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.

Re: How to retrieve the size of a procedure?
Posted: Thu Jan 14, 2010 6:24 pm
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.

Re: How to retrieve the size of a procedure?
Posted: Thu Jan 14, 2010 7:36 pm
by Kaeru Gaman
Demivec wrote:Regarding definition of 'bazaar', I believe srod meant 'bazarre' which means unusual or exotic.

that is written "b
izarre", I mentioned this vocable...
Re: How to retrieve the size of a procedure?
Posted: Thu Jan 14, 2010 7:40 pm
by srod
I did indeed mean bizarre!

Re: How to retrieve the size of a procedure?
Posted: Thu Jan 14, 2010 7:55 pm
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!
Re: How to retrieve the size of a procedure?
Posted: Thu Jan 14, 2010 7:58 pm
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.

Re: How to retrieve the size of a procedure?
Posted: Fri Jan 15, 2010 4:08 am
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.

Re: How to retrieve the size of a procedure?
Posted: Thu Jun 23, 2016 4:18 pm
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
Re: How to retrieve the size of a procedure?
Posted: Thu Jun 23, 2016 4:35 pm
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).
Re: How to retrieve the size of a procedure?
Posted: Thu Jun 23, 2016 4:53 pm
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
Re: How to retrieve the size of a procedure?
Posted: Thu Jun 23, 2016 10:44 pm
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.
Re: How to retrieve the size of a procedure?
Posted: Fri Jun 24, 2016 5:22 am
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.
Re: How to retrieve the size of a procedure?
Posted: Sat Jun 25, 2016 12:39 pm
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.