2

Sometimes when reversing the code - I see that each linked file is separated by these functions:

  • _$E19
  • _$E18

sometimes - there is no such separation (depending on the degree of compiler optimization).

What is their meaning?

.text:0000021C
.text:0000021C ; =============== S U B R O U T I N E =======================================
.text:0000021C
.text:0000021C
.text:0000021C _$E19           proc near               ; DATA XREF: .CRT$XCU:_$S20o
.text:0000021C                 mov     cl, byte ptr ds:??_B?1???id@?$ctype@G@std@@$D@@9@51
.text:00000222                 mov     al, 1
.text:00000224                 test    al, cl
.text:00000226                 jnz     short loc_230
.text:00000228                 or      cl, al
.text:0000022A                 mov     byte ptr ds:??_B?1???id@?$ctype@G@std@@$D@@9@51, cl
.text:00000230
.text:00000230 loc_230:                                ; CODE XREF: _$E19+Aj
.text:00000230                 jmp     _$E18
.text:00000230 _$E19           endp
.text:00000230
.text:00000230 ; ---------------------------------------------------------------------------
.text:00000235                 db 7 dup(90h)
.text:00000235 _text           ends
.text:00000235
.text:0000023C ; ===========================================================================
.text:0000023C
.text:0000023C ; Segment type: Pure code
.text:0000023C ; Segment permissions: Read/Execute
.text:0000023C _text           segment para public 'CODE' use32
.text:0000023C                 assume cs:_text
.text:0000023C                 ;org 23Ch
.text:0000023C ; COMDAT (pick no duplicate)
.text:0000023C                 assume es:nothing, ss:nothing, ds:_CRT$XCU, fs:nothing, gs:nothing
.text:0000023C
.text:0000023C ; =============== S U B R O U T I N E =======================================
.text:0000023C
.text:0000023C
.text:0000023C _$E18           proc near               ; CODE XREF: _$E19:loc_230j
.text:0000023C                 push    offset ?id@?$ctype@G@std@@$E ; void (__cdecl *)()
.text:00000241                 call    _atexit
.text:00000246                 pop     ecx
.text:00000247                 retn
.text:00000247 _$E18           endp
.text:00000247
.text:00000247 ; ---------------------------------------------------------------------------
.text:00000248                 db 4 dup(90h)
.text:00000248 _text           ends
.text:00000248

for example:

class aa
{
public:
    aa();
    ~aa();
    void fun();
};


class bb
{
public:
    bb();
    ~bb();
    void fun();
};


class cc
{
public:
    cc();
    ~cc();
    void fun();
};

// IMPLEMENTATION

aa::aa()
{

}

aa::~aa()
{

}

void aa::fun()
{
    printf("aa called");
}
// ------------------------
bb::bb()
{

}

bb::~bb()
{

}

void bb::fun()
{
    printf("bb called");
    std::string s = "asd";  // <------------ reason
}
// --------------------------
cc::cc()
{

}

cc::~cc()
{

}

void cc::fun()
{
    printf("cc called");
}

generates this list of functions:

aa::aa(void)   
aa::~aa(void)  
aa::fun(void)  
bb::bb(void)   
bb::~bb(void)  
bb::fun(void)  
std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Grow(uint,bool)
std::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Copy(uint)
$E19      
$E18      
[thunk]:std::ctype<ushort>::id`template static data member destructor helper'   
cc::cc(void)
cc::~cc(void) 
cc::fun(void) 
_main         
_printf       

But, the global variable initialized by the functions (_$E19, _$E18) is never used.


i'm vote for the new tag: code-generation

2
  • Now I do not know about the other surrounding code. Is this C++ code originally? The mangled names would suggest it. Either way given the available context, I would wager that some sort of static initializer (or a ctor) is involved here and that _$E19 is the code that registers or unregisters (00000224 with subsequent jnz or "fallthrough") the routine referenced at 0000023C with atexit. Now, I could be wrong and without further context I won't dare to answer this, but perhaps it helps you on your way to find out.
    – 0xC0000022L
    Commented Nov 11, 2022 at 9:22
  • Also, could it be that this only appears in objects built with RTTI enabled?
    – 0xC0000022L
    Commented Nov 11, 2022 at 9:24

1 Answer 1

2

you should potentially provide what tool was used to disassemble the code in query (ida , dumpbin , others etc )
also you should give the compiler unit (gcc, clang , vc etc )

is that an object file you have disassembled ?

anyway .CRT$XCU: section is a ms specific section where vs puts the user defined global initializers are (others like .CRT$XCA and .CRT$XCZ. also exist

_$E19
jmp     _$E18
_$E18           proc near 

these are labels

4
  • But the section names would not be in the .exe anymore. AFAIK they get all merged and the sole point of the .CRT section along with the respective $-specifiers is to influence ordering of objects at link time.
    – 0xC0000022L
    Commented Nov 11, 2022 at 9:13
  • @blabb this is really more commentary than an answer. And I really appreciate and enjoy reading your answers normally. I agree with rce that from the context it's clear this must be an object file and that it's likely MSVC-specific.
    – 0xC0000022L
    Commented Nov 11, 2022 at 9:16
  • 2
    as the linked article says .crtcxu is likely to be placed at the end after .crtcxa ... and normally these labels that would be visible on object file disassembly tend to disappear in binary ( i see this notion is contradicted in comment ) try compiling the code in linked article the whole .crtcxu section which will be visible in object file iwill disappear after linking into binary
    – blabb
    Commented Nov 11, 2022 at 13:03
  • I merely meant to point out that the section names may change within the .exe, not that the object file wouldn't contain the original names. It was more aimed at the comment from @rce.
    – 0xC0000022L
    Commented Dec 11, 2022 at 20:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.