When I added 20 more characters to the end of DbgFoundText, the program chokes.
Is there a length limit to MB_OK | MB_ICONEXCLAMATION?
DbgFoundText db "Debugger found!",0h
PUSH 30h ; Show badboy
PUSH offset DbgFoundTitle
PUSH offset DbgFoundText
PUSH 0
CALL MessageBox
no - it will almost fill the screen, if it needs to
actually - there may be some practical limit, but it will wrap and crop text, too
i think i put 32 k of text in one, once - something like that
i am guessing that you are overwriting something when you add 20 characters
as you have it shown, the text is in the code section
you would be overwriting the message box code :P
DbgFoundText db "Debugger found!",0h,20 dup(?)
PUSH 30h ; Show badboy
PUSH offset DbgFoundTitle
PUSH offset DbgFoundText
PUSH 0
CALL MessageBox
It's not in the code section, just had it there to show my text.
Here is the entire code, it may be another issue.
More comments at the end to show what the code does and 2 modifications that need to be done to the P.E header.
; TLS_Callback.asm
;
; Now, clicking back in the Data Directories, double-click in the TLS Directory RVA and change it to 3046.
; Then change the TLS Size to 18. Now save the binary.
; Random,
;
.586
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\comdlg32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comdlg32.lib
.data
DbgNotFoundTitle db "Debugger status:",0h
DbgFoundTitle db "Debugger status:",0h
DbgNotFoundText db "Debugger not found!",0h
DbgFoundText db "Debugger found!",0h
; TLS Structure
dd offset StartAddress
dd offset EndAddress
dd offset AddressOfIndex
dd offset TlsCallBack
TlsCallBack dd offset TLS ; Address of our callback
dd 0 ; Spacer
dd 0 ; Spacer
StartAddress dd 0
EndAddress dd 0
AddressOfIndex dd 0
TlsCallBack2 dd offset TLS
SizeOfZeroFill dd 0
Characteristics dd 0
.data?
TLSCalled db ? ; Flag for if TLS has been called
.code
start:
invoke ExitProcess,0 ; Main routine does nothing
ret
; TLSCallback
TLS:
CMP BYTE PTR[TLSCalled],1 ; If callback has already been run
JE @exit ; ignore it
MOV BYTE PTR[TLSCalled],1 ; Set flag for next time
CALL IsDebuggerPresent
CMP EAX,1 ; Are we being debugged?
JE @DebuggerDetected ; yes
PUSH 40h ; Show goodboy
PUSH offset DbgNotFoundTitle
PUSH offset DbgNotFoundText
PUSH 0
CALL MessageBox
JMP @exit
@DebuggerDetected:
PUSH 30h ; Show badboy
PUSH offset DbgFoundTitle
PUSH offset DbgFoundText
PUSH 0
CALL MessageBox
@exit:
RET
end start
Introduction
TLS stands for Thread Local Storage. As you probably know, threads are execution entities that run inside
of a process. Programs make use of threads when they wish to accomplish multiple actions concurrently,
even though sometimes 'concurrently' is just an illusion. For example, let's say you want to print a
document. You press the 'print' button and the program formats the document and sends it to the printer.
This activity would be run in a separate thread. The reason for this is we do not want to stop down the
entire application until the document is done printing. We want it to start the print process and then
immediately return to us, perhaps to do some work while it's printing.
If you have multiple processors, each thread can run on a separate processor. This can speed up
applications as multiple processors can be doing work at the same time. Concurrency can also benefit
from a single processor system. Take for example our print scenario above. Once the application sends the
document off to the printer, the application will sit around, waiting for the printing activity to finish.
This is a LOT of time, especially for a processor. During this waiting time, we can be doing other things.
Threads allow a processor to split up activities, and while waiting for a response from one, can be working on
another.
When these multiple threads are created, they usually share the same memory. For example, if we have
an address book application and we decide to print a contact, the print thread will begin and have access
to the main contact data. If, right after we start the print thread, we want to start another thread that begins showing the contact data on the screen (after all, the print dialog covered some of it), this new thread also has access to the contact data.
Threads access this pooled memory by calling the same addresses. In other words, thread A calls address
1000 to get the first contact, and thread B calls 1000 and gets the same data. The two addresses are the
same. But what happens when we want a thread to have it's own data? Perhaps we want the printing
thread to have a variable for if the printing was successful or not. All threads do not need to have this
variable. Therefore, this thread needs a 'local' variable, one that only that specific thread has access to.
This becomes really important when a single thread needs access to a large class or union. We do not
want every thread started to have access to such a large chunk of memory.
Windows provides a way that a thread can have it's own 'local storage'. This storage is similar to a stack,
but is only accessible to a specific thread. There is a certain chunk of memory that will be reserved for this
thread, and variables can be stored in it. This way, only this one thread has access.
We can also set up the threads so that they all have a local copy of a variable, but they all access it
through the same address. For example, we could have a count variable in every thread, and every thread
accesses it through memory location 1000. But they are all different. Even though they are all the same
address, Windows separates each thread's storage, so that location 1000 to thread A will not be the same
variable (in memory) as thread B.
This TLS storage area can be used for other, often malicious, activities. Code can be put into this TLS
section and can be run. The interesting thing about this is that the TLS code will run BEFORE the main
entry point of the binary is run. When the Windows loader first loads the binary into memory, right after it
loads in the DLLs needed, it checks a location in the PE header to see if there is a TLS section set up, and
if there is, it looks for a callback address. If one is provided, this address is called, and the code in this
section is run. After this runs, the loader then hands control over to the main application.
What all this boils down to is that when you load a binary into a debugger, often times we have the
debugger set to stop at the module's main entry point. Once our debugger has stopped here, our TLS
code has already been run. This code can do many things including checking for a debugger, infecting a
system, or formatting a hard drive. And an unwary (or unskilled) programmer will load this binary into
Olly, and before you know it, your system is infected (or worse).
You may see this behavior empirically when you load a binary into Olly and the program immediately
terminates, without ever touching any code in the actual main module. If this ever happens, your first
thought should always be check for a TLS section.
still - it wouldn't hurt to declare an extra buffer for the appended text
see my previous post
DbgFoundText db "Debugger found!",0h,20 dup(?)
Quote from: Magnum on April 15, 2013, 10:30:15 AM
More comments at the end to show what the code does and 2 modifications that need to be done to the P.E header.
There's no need at all to patch the PE header manually to add a TLS directory. There's an official way to make the linker add this info: define public variable _tls_used ( type IMAGE_TLS_DIRECTORY32 ).
I tried this but it said "in structure."
_tls_used IMAGE_TLS_DIRECTORY32
Quote from: Magnum on April 15, 2013, 11:21:08 PM
I tried this but it said "in structure."
_tls_used IMAGE_TLS_DIRECTORY32
poor script kiddie :eusa_boohoo:
Quote from: qWord on April 15, 2013, 11:58:43 PM
poor script kiddie :eusa_boohoo:
lol - it's the campus, qWord :P
Andy, try this
_tls_used IMAGE_TLS_DIRECTORY32 <>
if you want to know how it's defined, you can use the windows explorer search tool
go to the \masm32\include folder
search for files containing the text "IMAGE_TLS_DIRECTORY32"
you will see that it's defined in windows.inc
now, open windows.inc with notepad, and search for the same string
there are at least 3 ways to make it public - i'll let you figure that out :biggrin:
Thanks dave.
I think qWord was bullied as a kiddie and he thinks his anger is normal. :dazzled:
qWord and japheth are excellent coders
when you are very, very good at something, it's easy to forget what it was like when you started out
Hi Dave,
Quote from: dedndave on April 16, 2013, 02:51:21 AM
qWord and japheth are excellent coders
when you are very, very good at something, it's easy to forget what it was like when you started out
but it's always good to know where you come from.
Gunther
Quote from: Magnum on April 15, 2013, 11:21:08 PM
I tried this but it said "in structure."
"In structure" seems not to be a known Masm error. :icon_eek:
We're in the campus, that means you should try to express yourself in full sentences with proper citations and not use some kind of "Texas slang".
Here's a full sample how static TLS can be used: http://www.japheth.de/JWasm/Win32Tls.html (http://www.japheth.de/JWasm/Win32Tls.html)
Hi Andreas,
Quote from: japheth on April 16, 2013, 03:59:01 AM
Here's a full sample how static TLS can be used: http://www.japheth.de/JWasm/Win32Tls.html (http://www.japheth.de/JWasm/Win32Tls.html)
good link. Thank you. :t
Gunther
Gunther and Dave,
Don't worry about me, I have a good working example.
If someone throws out a suggestion to improve my code, then I check it out.
It's a fact of life that some folks are just miserable and don't cheerfully want to help others.
For every cranky one, there are 50 others who gladly help.
So, I stay happy and they stay unhappy.
Andy
Quote from: Magnum on April 16, 2013, 06:25:06 AM
Don't worry about me, ...
I don't know if Dave or Gunther are worried, but I am. It's because you're ovbviously doing stuff "beyond your league", and this means, in other words, that you're predestined to shoot yourself in the foot.
So, just see me as a somewhat strict, but nevertheless loving father who wants the best for his inexperienced and slightly ill-mannered child.
Quote from: japheth on April 16, 2013, 08:27:48 PMloving father
You could adopt Andy. That is, if you like the idea of becoming a multiple grandfather :icon_mrgreen:
You are certainly entitled to your opinion.
As a scientist, it is my opinion that you are making predictions based on little or faulty data.
But there are no hard feelings on my part for stating what's is on your mind.
Andy
This compiles o.k. and creates the TLS section but the program doesn't work.
Application failed to initialize properly.
Andy
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\comdlg32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comdlg32.lib
IMAGE_TLS_DIRECTORY32 STRUCT
StartAddressOfRawData dd ?
EndAddressOfRawData dd ?
AddressOfIndex dd ?
AddressOfCallBacks dd ?
SizeOfZeroFill dd ?
Characteristics dd ?
IMAGE_TLS_DIRECTORY32 ENDS
.CONST
public _tls_used ;tell the linker that a TLS directory is wanted
.data
DbgNotFoundTitle db "Debugger status:",0h
DbgFoundTitle db "Debugger status:",0h
DbgNotFoundText db "Debugger not found!",0h
DbgFoundText db "Debugger found!",0h
_tls_used IMAGE_TLS_DIRECTORY32 <>
; TLS Structure
dd offset StartAddress
dd offset EndAddress
dd offset AddressOfIndex
dd offset TlsCallBack
TlsCallBack dd offset TLS ; Address of our callback
dd 0 ; Spacer
dd 0 ; Spacer
StartAddress dd 0
EndAddress dd 0
AddressOfIndex dd 0
TlsCallBack2 dd offset TLS
SizeOfZeroFill dd 0
Characteristics dd 0
.data?
TLSCalled db ? ; Flag for if TLS has been called
.code
start:
invoke ExitProcess,0 ; Main routine does nothing
ret
; TLSCallback
TLS:
CMP BYTE PTR[TLSCalled],1 ; If callback has already been run
JE @exit ; ignore it
MOV BYTE PTR[TLSCalled],1 ; Set flag for next time
CALL IsDebuggerPresent
CMP EAX,1 ; Are we being debugged?
JE @DebuggerDetected ; yes
PUSH 40h ; Show goodboy
PUSH offset DbgNotFoundTitle
PUSH offset DbgNotFoundText
PUSH 0
CALL MessageBox
JMP @exit
@DebuggerDetected:
PUSH 30h ; Show badboy
PUSH offset DbgFoundTitle
PUSH offset DbgFoundText
PUSH 0
CALL MessageBox
@exit:
RET
end start
IMAGE_TLS_DIRECTORY32 STRUCT
StartAddressOfRawData dd ?
EndAddressOfRawData dd ?
AddressOfIndex dd ?
AddressOfCallBacks dd ?
SizeOfZeroFill dd ?
Characteristics dd ?
IMAGE_TLS_DIRECTORY32 ENDS
the structure is already defined in windows.inc
.CONST
public _tls_used ;tell the linker that a TLS directory is wanted
it isn't necessary to open a segment to declare a symbol as public
.data
_tls_used IMAGE_TLS_DIRECTORY32 <>
here, you have declared a _tls_used structure
the elements may be accessed in code using a period, for example
mov eax,_tls_used.StartAddressOfRawData
furthermore, the element values may be initialized when defined
_tls_used IMAGE_TLS_DIRECTORY32 <StartAddress,EndAddress,AddressOfIndex,TLS,0,0>
; TLS Structure
dd offset StartAddress
dd offset EndAddress
dd offset AddressOfIndex
dd offset TlsCallBack
TlsCallBack dd offset TLS ; Address of our callback
dd 0 ; Spacer
dd 0 ; Spacer
StartAddress dd 0
EndAddress dd 0
AddressOfIndex dd 0
TlsCallBack2 dd offset TLS
SizeOfZeroFill dd 0
Characteristics dd 0
here, you are attempting to declare another structure in another way :eusa_naughty:
What you said makes sense, but I don't understand much of what the code is doing or supposed to be doing.
Andy
Here is a sample of use with some modifies.
The Cstr macro in html page need to be modify.
Many data was in the .const segment
The TLS segment made the .exe work as a dll,see the sample.
.486
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
TlsCallBack1 PROTO :DWORD,:DWORD,:DWORD
TlsCallBack2 PROTO :DWORD,:DWORD,:DWORD
.DATA
DbgNotFoundTitle db "Debugger status:",0h
DbgFoundTitle db "Debugger status:",0h
DbgNotFoundText db "Debugger not found!",0h
DbgFoundText db "Debugger found!",0h
msgCaption1 db "TLS Callback *1*",0
msgCaption2 db "TLS Callback *2*",0
; TLS Callbacks are called like DLL entry proc
;DLL_PROCESS_DETACH equ 0
;DLL_PROCESS_ATTACH equ 1
;DLL_THREAD_ATTACH equ 2
;DLL_THREAD_DETACH equ 3
msgText dd offset szDLL_PROCESS_DETACH
dd offset szDLL_PROCESS_ATTACH
dd offset szDLL_THREAD_ATTACH
dd offset szDLL_THREAD_DETACH
szDLL_PROCESS_DETACH db "TLS Callback running with Reason",0Dh,0Ah,0Dh,0Ah," DLL_PROCESS_DETACH",0
szDLL_PROCESS_ATTACH db "TLS Callback running with Reason",0Dh,0Ah,0Dh,0Ah," DLL_PROCESS_ATTACH",0
szDLL_THREAD_ATTACH db "TLS Callback running with Reason",0Dh,0Ah,0Dh,0Ah," DLL_THREAD_ATTACH",0
szDLL_THREAD_DETACH db "TLS Callback running with Reason",0Dh,0Ah,0Dh,0Ah," DLL_THREAD_DETACH",0
align 4
; Null terminated list of pointers to callback procedures
Callbacks DWORD TlsCallBack1, TlsCallBack2, 0
PUBLIC _tls_used ; this name is required and must be PUBLIC!!!!
_tls_used IMAGE_TLS_DIRECTORY < _tls_start, _tls_end, _tls_index, Callbacks, 0, 0 >
.DATA?
_tls_index DWORD ?
TLSCalled db ? ; Flag for if TLS has been called
; Create a section with name .tls
OPTION DOTNAME
.tls SEGMENT
_tls_start LABEL DWORD
DWORD 80H DUP ("slt.")
_tls_end LABEL DWORD
.tls ENDS
OPTION NODOTNAME
.CODE
TlsCallBack1 proc uses ebx hInst:HINSTANCE, reason:DWORD, lpReserved:DWORD
mov ebx, reason
shl ebx, 2
invoke MessageBox, NULL, msgText[ebx], ADDR msgCaption1,MB_OK+MB_TASKMODAL+MB_TOPMOST
mov eax, TRUE
ret
TlsCallBack1 endp
TlsCallBack2 proc uses ebx hInst:HINSTANCE, reason:DWORD, lpReserved:DWORD
mov ebx, reason
shl ebx, 2
invoke MessageBox, NULL, msgText[ebx], ADDR msgCaption2,MB_OK+MB_TASKMODAL+MB_TOPMOST
; TLSCallback
TLS:
CMP BYTE PTR[TLSCalled],1 ; If callback has already been run
JE @exit ; ignore it
MOV BYTE PTR[TLSCalled],1 ; Set flag for next time
CALL IsDebuggerPresent
CMP EAX,1 ; Are we being debugged?
JE @DebuggerDetected ; yes
PUSH 40h ; Show goodboy
PUSH offset DbgNotFoundTitle
PUSH offset DbgNotFoundText
PUSH 0
CALL MessageBox
JMP @exit
@DebuggerDetected:
PUSH 30h ; Show badboy
PUSH offset DbgFoundTitle
PUSH offset DbgFoundText
PUSH 0
CALL MessageBox
@exit:
mov eax, TRUE
ret
TlsCallBack2 endp
start:
invoke GetModuleHandle, NULL
invoke ExitProcess, 0
end start
Thanks to both you gentleman.
I am studying your code.
Andy
This one is a translate from msdn and don't need a segment.