PE format eighth, TLS table (thread-local storage)
Ibinary
Source: http://www.cnblogs.com/iBinary/
All rights reserved, welcome to keep the original link to reprint:)
I. Review thread-related knowledge
The first time to explain the TLS, you need to review thread-related knowledge (thread local storage)
1. Understanding Classic Sync Issues
First we write a C + + code, open two threads to run to see if there will be synchronization problems.
The result is that the result is not correct, and the cause of the synchronization problem is that two threads are accessing the same variable.
Solve the problem:
1. Use the synchronization object. (Spin lock self-lock mutex event semaphore critical area .....) And so on, all can.)
The use of self-locking is used here to solve (of course, you can use other)
InterlockedIncrement API
Prototype:
LONG interlockedincrement ( lplong volatile lpaddend //variable to increment);
Just take the address of the global variable to it, strong to long * type.
The result is correct after use
Second, what is TLS (Thread local storage)
The so-called TLS means that each thread has its own space, local storage, what does it mean?
For example, we're working on a g_dwnumber, so we're going to use a synchronous object, and we might as well think of each thread as a space
When operating on a thread, the g_dwnumber of the A thread is manipulated, and when the B thread is manipulated, the g_dwnumber of the B thread is manipulated.
Actually very simple, introduce the TLS API
A total of 4
PE format eighth, TLS table (thread-local storage) One, review thread-related knowledge
The first time to explain the TLS, you need to review thread-related knowledge (thread local storage)
1. Understanding Classic Sync Issues
First we write a C + + code, open two threads to run to see if there will be synchronization problems.
The result is that the result is not correct, and the cause of the synchronization problem is that two threads are accessing the same variable.
Solve the problem:
1. Use the synchronization object. (Spin lock self-lock mutex event semaphore critical area .....) And so on, all can.)
The use of self-locking is used here to solve (of course, you can use other)
InterlockedIncrement API
Prototype:
LONG interlockedincrement ( lplong volatile lpaddend //variable to increment);
Just take the address of the global variable to it, strong to long * type.
The result is correct after use
Second, what is TLS (Thread local storage)
The so-called TLS means that each thread has its own space, local storage, what does it mean?
For example, we're working on a g_dwnumber, so we're going to use a synchronous object, and we might as well think of each thread as a space
When operating on a thread, the g_dwnumber of the A thread is manipulated, and when the B thread is manipulated, the g_dwnumber of the B thread is manipulated.
Actually very simple, introduce the TLS API
A total of 4
PE format eighth, TLS table (thread-local storage) One, review thread-related knowledge
The first time to explain the TLS, you need to review thread-related knowledge (thread local storage)
1. Understanding Classic Sync Issues
First we write a C + + code, open two threads to run to see if there will be synchronization problems.
The result is that the result is not correct, and the cause of the synchronization problem is that two threads are accessing the same variable.
Solve the problem:
1. Use the synchronization object. (Spin lock self-lock mutex event semaphore critical area .....) And so on, all can.)
The use of self-locking is used here to solve (of course, you can use other)
InterlockedIncrement API
Prototype:
LONG interlockedincrement ( lplong volatile lpaddend //variable to increment);
Just take the address of the global variable to it, strong to long * type.
The result is correct after use
Second, what is TLS (Thread local storage)
The so-called TLS means that each thread has its own space, local storage, what does it mean?
For example, we're working on a g_dwnumber, so we're going to use a synchronous object, and we might as well think of each thread as a space
When operating on a thread, the g_dwnumber of the A thread is manipulated, and when the B thread is manipulated, the g_dwnumber of the B thread is manipulated.
Actually very simple, introduce the TLS API
A total of 4
PE format eighth, TLS table (thread-local storage) One, review thread-related knowledge
The first time to explain the TLS, you need to review thread-related knowledge (thread local storage)
1. Understanding Classic Sync Issues
First we write a C + + code, open two threads to run to see if there will be synchronization problems.
The result is that the result is not correct, and the cause of the synchronization problem is that two threads are accessing the same variable.
Solve the problem:
1. Use the synchronization object. (Spin lock self-lock mutex event semaphore critical area .....) And so on, all can.)
The use of self-locking is used here to solve (of course, you can use other)
InterlockedIncrement API
Prototype:
LONG interlockedincrement ( lplong volatile lpaddend //variable to increment);
Just take the address of the global variable to it, strong to long * type.
The result is correct after use
Second, what is TLS (Thread local storage)
The so-called TLS means that each thread has its own space, local storage, what does it mean?
For example, we're working on a g_dwnumber, so we're going to use a synchronous object, and we might as well think of each thread as a space
When operating on a thread, the g_dwnumber of the A thread is manipulated, and when the B thread is manipulated, the g_dwnumber of the B thread is manipulated.
Actually very simple, introduce the TLS API
A total of 4
respectively:
TlsAlloc allocating thread-local storage space
TlsFree releasing thread-local storage space
TlsGetValue gets the value inside the thread's local storage space
TlsSetValue setting the value of thread-local storage space
Third, the use of TLSAPI
1. First is the use of TlsAlloc
DWORD TlsAlloc (VOID); Function prototypes
calling a TlsAlloc will allocate 4 bytes of space, no matter where you call it, if you call it in main thread, then when you create it
the thread defaults to a 4-byte control
The return value is an index, which is the value of the FS register array of course, this one will explain. Just know, when we request 4 bytes of space for each thread
then the index is the same, but the data for the index operation is not the same
like the index you're applying for is 1.
then in the A-thread, when the operation of the 1 index, then the operation is a thread, then if the B-thread operation index 1, then the operation of the B-thread data
Example:
like, there's a phone number, 12345678 .
China: 12345678
Foreign: 12345678 (call phone number as index)
we know that the phone number is the same, but when you make this call, people are different.
For example, I played 123456 in China, so the answer is Zhang San.
I play 123456 in a foreign country, so the answer is John Doe.
where Dick and Harry is the expression of different operations on the same data. Look at the code.
Another example:
we used TlsAlloc to request 4 bytes of space .
the index is nindex (seen as G_dwnumber);
then accessing the indexes of different threads, the values inside the index are different.
1.Tls dynamic use method, set global variables
Dynamic use is the non-establishment of a TLS table in PE, also complete synchronization
First, we open up 4 bytes of space for each thread
And then return an index (the index is a g_dwnumber, in fact the index is to go to the array to take out the members, for example, now is the 1th, then go to the array to remove the first item, as G_dwnumber)
TlsSetValue (index, set value)
This is actually based on the index to find the value inside the array, set a bit.
TlsGetValue (index) is the value of the G_dwnumber from the array, based on the subscript index.
And then reset it back. At the position of the 1 index, the value of G_dwnumber is set.
If the alignment data structure does not understand, you can see the work of the drawings
Array: [0][1][2][3] ..... Array First address: 00401000
Array: [0][1][2][3] ..... Array First address: 00402000
In fact, each thread can be understood as an index, but the values taken out of the array are not the same.
For example, the A thread has an index of 1, and its members are the g_dwnumber of a thread, for example, its value is now 5.
Now switch to the B thread, then the index to find the value, but the array is different, so looking again for 1 is the B array of G_dwnumber.
In fact, the role of the API is the equivalent of you manually to the array of elements to assign value, value. And so on.
This is just an array of operating system footprints, so provide you with an API
According to our wording, we may do the following, pseudocode, easy to understand
ATHREAD[1] = 0;
DWORD g_dwnumber = athread[1];
printf (g_dwnumber);
ATHREAD[1] = g_dwnumber++;
The replacement API is
TlsSetValue (index, value)
TlsGetValue (index);
Now look at that picture, then the synchronization has been achieved. The thread also switches, manipulating its own data.
2. Dynamic use of TLS for the structure of the body settings
We're talking about a global variable in the array, and now we're going to set up the structure.
The structure is actually the same, we have the pointer in the array to the line.
For example, look at the code below:
Very simple
1. We define a P pointer that points to a new memory
2. When initializing, sets the value of the current index of the array index to a pointer of P
3. Get the P pointer from the index
4. Modify the value of P-pointing M_dwcount
Note that because P is a pointer, we are only modifying the value of its space member variable, so we don't have to set it back again.
Now it feels like TLS is a bit hard to use. In fact, using TLS is faster than using any synchronization object, which is equivalent to the speed at which the synchronization is not synchronized.
But the real syntax of TLS is not so. (above is dynamic use does not generate TLS table)
Static use of 3.Tls (true usage)
In fact, the real usage of TLS is static use, the operating system has helped you integrate the syntax
Look at the usage, as well as the grammar;
Grammar:
__declspec (thread) type variable name
Then TLS will automatically generate the table, and the operating system can help you to upgrade the code used dynamically. (So why to understand dynamic use)
When used, it is normal to use.
We don't have to change the code.
But in fact the assembly code will be compiled for the above dynamic use.
If it becomes a struct, then it is the same, just turn the type into a struct type.
Design of TLS table in PE
Understanding the above principle, so if you design the table how you want to design?
1. Our global variables are initialized to 0, then we must have somewhere to store the data for this global variable, so I'll design a section to store this value.
2. The nindex index we commonly use, then I think I want to store it.
Don't talk nonsense, look at the real structure
struct _image_tls_directory32 { DWORD startaddressofrawdata; Start address of TLS initialization data DWORD endaddressofrawdata; The end address of the TLS initialization data Two a value that exactly locates a range, the range is set to initialize the DWORD addressofindex; Location of the TLS index DWORD addressofcallbacks; The array pointer of the TLS callback function, DWORD Sizeofzerofill; Number of padding 0 Union { DWORD characteristics; Retain struct { ; 4 ; 8 ; } Dummystructname; } Dummyunionname;} image_tls_directory32;
First, we introduce the top two members,
The start address end address locates a range, so this range is the initialized value (note that only the static use of the TLS table) is the above we define the G_dwnumber = 0, storage 0, but because 0 is not good to see, here I re-assigned to 12345678 code is not posted.
Let's look at the location of the PE to locate TLS.
Note, because I am VS2015 writing program, random base address is too lazy to go, directly in the PE modified, the file attributes of the header can be modified.
It used to be 02, now it's 03.
First look at the 9th item in the next data directory
To obtain RVA = 000176FC
View the first address of the module. The first address is 00400000.
See which section belongs to
Hit in the. Rdata section, RVA = 00016000
The above RVA minus the current RVA = offset
000176fc-00016000 = 16FC
The file offset in the section + offset = location in the file.
The file offset is a second member below
5400 + 16FC = 6AFC
View the location of the 6AFC locating TLS table.
The previous two members were pointing to the
0041b000 0041b208 location End address-start address = range.
Find the FA for the starting address
Time relationship, where the hit section is Rva = 001b000
Then shift to file offset
FA = 8400h is calculated directly.
The starting address is 8400h then +208 is 8608, then 8400h to 8608 of the location of the initial value of the storage, and now see the drawing of 12345678 (small tail way to read)
3rd member: The value of the index, which you can convert yourself to view.
Five, TLS struct fourth member, array pointer of callback function
This How to understand, is this, also remember the dynamic use of time, we are not in the main thread TlsAlloc and TlsFree?
Now that we can register the callback function, the operating system calls the callback function.
How to register?
Keywords: add segment, must be added to specific groud
First look at the function prototype of the callback.
typedef VOID (Ntapi *pimage_tls_callback) (PVOID dllhandle, DWORD reason,pvoid Reserved);
Pimage_tls_callback where this callback is from the fourth member of the struct, the comment gets
First we write ourselves a
Look at the note, in fact, this is the real application and release, note that the callback function operating system will read the address from the asking price, and then execute it again, did not request memory, so this can hide code.
Note that although the callback we wrote, but for the operating system to invoke, then we need to add a specific section.
Grammar:
#pragma data_seg (". Crt$xlb ") which about. Crt$xlb Why this is the festival, I sent a link to see the Snow forum, I see it, very simple. https://bbs.pediy.com/thread-108015.htm
/* Middle Write code, define function callback array */
Pimage_tls_callback ary[] = {mytlscallback,0}; 0 end, then the operating system will find this location in the file, call this callback. If multiple, the inside can write multiple, 0 ending can be.
#pragma data_seg ();
Discover that 1 has been successfully bounced, so now the fourth member of the struct is pointing to the first address of the array. When the PE is loaded, it is called by default and then executed again.
Note that it is only stored in the file, and if you run into memory to view it, this address is not.
It's too late, it's almost 4 o'clock, and the rest of the bytes will be said tomorrow.
Ibinary
Source: http://www.cnblogs.com/iBinary/
All rights reserved, welcome to keep the original link to reprint:)
PE format eighth, TLS table (thread-local storage)