Non-returning functions, "why is this function not analyzed if there's clearly code after it?!" or "what is this gray line in disassembler view?!"
Oh, this is a gross one. A newbie like me could waste hours trying to understand what the hell was up. It's an undocumented nightmare.
Live reaction
The first sign of dealing with a non-returning function is this god damn gray line in IDA View that tortures the souls of those who don't know.
The gray line in question
As evident by the compound adjective "non-returning", this function is deemed to never return. Generally, a function never returns if it terminates the application or the executive thread - it doesn't need to return because it'll never have the chance to. IDA Pro slaps __noreturn on every function that doesn't have a single ret or jmp instruction, which makes sense, but... It really doesn't. This logic works until the function in question is, for example, forged by a protector:
This function does a bunch of weird stuff and then calls another function. "But this function never returns!" - one would think.
Indeed, in a normal function that does this, sub_7FFFC19BA92C may never return by doing some action like exiting the app.
But this is forged, either manually or by VMProtect, so "normal" rules don't apply here. The function will return eventually.
How is that possible? Well, call pushes the return address to the stack. In a call A->call B chain, there will be 2 return addresses, O <- A and A <- B. Pop the first one (being the return from B to A) and ret to the second one. Congratulations: you returned back to the original caller, O. Believe it or not, IDA Pro can recover from some kinds of call-returns done this way, usually if there's a well-formed chain the decompiler can follow. It just doesn't always work. But you're not here for the technicalities, are you? Let's review how to get rid of this gray line already.