Live data from Hacker News

Please restore our registers when you’re done with them

randomascii.wordpress.com

101–110 of 142 posts

Re: Please restore our registers when you’re done with them

#101

Earlier quoted context omitted.

I'd love to see Chrome and Firefox and IE working together to detect this kind of thing and put up a malware warning explaining how to uninstall it, and see how quickly it can be eliminated. Seriously, there is zero valid reason to ever inject code into another program, other than as a debugging tool on a system being debugged.

The modding communities for Bethesda games rely heavily on code injection, especially the script extender plugins that are central to the entire enterprise.

Yeah, but there's ZERO reasons why you should be allowed to modify software to suit you. ZERO. Security über alles, DRM control over all, how dare you modify the software God Developer has given you, it will make you Insecure.

Re: Please restore our registers when you’re done with them

#102

Earlier quoted context omitted.

I'd love to see Chrome and Firefox and IE working together to detect this kind of thing and put up a malware warning explaining how to uninstall it, and see how quickly it can be eliminated. Seriously, there is zero valid reason to ever inject code into another program, other than as a debugging tool on a system being debugged.

On Windows, you can call "EnumProcessModules" to get all the DLLs loaded in the current process – and check those are what you expect. It is potentially a bit fragile though - DLLs can load other DLLs, and it has happened before that in a new Windows version, Microsoft suddenly adds new implementation DLLs which get pulled in by the main system DLLs. One approach might be to look at code-signing on all the DLLs, and…

What's more likely to happen is that IT tells people to ignore the scary warning, and scary warnings become less effective.

Re: Please restore our registers when you’re done with them

#103
post #81

Earlier quoted context omitted.

I'd love to see Chrome and Firefox and IE working together to detect this kind of thing and put up a malware warning explaining how to uninstall it, and see how quickly it can be eliminated. Seriously, there is zero valid reason to ever inject code into another program, other than as a debugging tool on a system being debugged.

There might be a few more. Invasive Anti cheat software seems necessary for competitive multiplayer games on PC.

DLL injection is also used for in-game overlays by Steam/Discord/etc, and I'm not aware of a better method they could use instead given that they're expected to work for games that were never made with those services in mind.

Re: Please restore our registers when you’re done with them

#104
post #6

Earlier quoted context omitted.

Yeah, something like "mov ax, 0h" but I suppose that is way more memory intensive as you have to load a 0 into memory somewhere and then copy it into the register. It strikes me as somehow the compiler is making assumptions that aren't being enforced by the ... OS? Language? not sure what, but it's assuming functions restore registers used but that isn't enforced by anything. From my (long ago) time there was PUSHA a…

Why would you have to load 0 into memory somewhere (other than in the instruction itself)? Or did you mean that it is in fact in the instruction?

Because you’d either need a special “always zero” register (some chips have this), or a menomic for some or all of the instructions that assume zero as an operable (some chips have this), or wipe a register (this is the problem here - uses a register) or use memory.

Adding an implicit zero may make sense for some instructions but probably not all.

Re: Please restore our registers when you’re done with them

#105

I think the real fix is to set all registers to a canary value at the start of int main(), and then when exiting check the canary value is still there. If anything has messed with any registers without permission, you crash and collect as much data as possible about any injected dll's. Then you correlate these to find the culprits, and for each you contact the authors of the DLL and figure out a way to block the inje…

Any good function upstream of the bad one that also uses the same register will mask the issue

Re: Please restore our registers when you’re done with them

#106

Earlier quoted context omitted.

Why would you have to load 0 into memory somewhere (other than in the instruction itself)? Or did you mean that it is in fact in the instruction?

Because you’d either need a special “always zero” register (some chips have this), or a menomic for some or all of the instructions that assume zero as an operable (some chips have this), or wipe a register (this is the problem here - uses a register) or use memory. Adding an implicit zero may make sense for some instructions but probably not all.

Look at the format of the 68000's MOVEQ instruction. The zero is part of the instruction, and does not take an extra four bytes to hold it. There's no memory that's used (other than the instruction itself), no extra memory to hold the argument, and no "always zero" register.

MOVEQ can move more than a zero. It can move any small number (-128 to 127), so 0 is not "special" here.

Also check out the CLR instruction (though that may be what you meant by "a mnemonic for some or all of the instructions that assume zero").

Re: Please restore our registers when you’re done with them

#107
post #75

Earlier quoted context omitted.

My reading of it was that the bug was caused by XMM7 not being restored to its previous value. E.g. on Linux, functions should restore the values of ebx, esi, edi, ... once they're done with them. The article says (on Windows) that XMM7 needs to be restored too. If you can't trust one register being preserved (per the ABI), then you really can't trust the values of any registers.

Fair point, which is why I used the phrase "this particular example." In fact the compiler's lazy assumption about XMM7 was the key to determining that the ABI was being violated. It would have taken longer to figure this out if the compiler had been doing things my way, because then a failure of the callee to preserve XMM7 wouldn't have mattered.

What's the point of having an ABI if you can't assume it's being used?

If you don't want to trust any callees, you could use an ABI with all registers caller saves, but I don't think any mainstream ABIs are like that.

There's a balance where having some registers be caller saved and others callee saved means a lot less saving required.

Re: Please restore our registers when you’re done with them

#108
post #63

Earlier quoted context omitted.

Where it's not optimized away, getting "an actual zero" requires a memory operation of some kind. Register ops are faster in that they are right there, no fetch needed.

Depends on the instruction architecture. 68000 had some ways of burying a small literal operand in the instruction. If I recall correctly, MOVEQ.L would let you move zero to a register without touching memory (other than the instruction fetch), and it wasn't a long instruction.

Yes, that is true.

However, moving a zero to a register does take time. Time that would otherwise be used operating with the zero value already present in the zero register.

The second best is what moto did. As you point out, there is the instruction fetch, which could be the intended operation, rather than developing the zero itself.

On par with that is having enough registers to just hold a zero, and whether that made sense depended on the need and developer strategy.

I am a big fan of the moto CPU's, starting with the 6809. Just to be clear.

Re: Please restore our registers when you’re done with them

#109

I'm sure some C++ lawyer can correct me, but isn't branching off of `m_ptr` (e.g. `CHECK()`ing the value) after `std::move(m_ptr)` technically Unspecified Behavior since `std::move(m_ptr)` leaves `m_ptr` as an Unspecified Value? It would be up to the compiler to define the behavior if they so pleased, but the C++ spec would not require such behavior to be defined at all.

I was wondering if anybody was going to point that out. It did occur to me that the CHECK was not technically valid due to that exact concern, but given that we control the compiler and the C++ library implementation and given that it's just debugging code (albeit debugging code that we ship to users) I'm fine with it. In other words, I guess you shouldn't oughta do that generally, but I was fine with it being used t…

It appears that the question of what is valid on a moved-from object is tricky. Here is one discussion: https://stackoverflow.com/questions/7027523/what-can-i-do-wi... FWIW, here is the move operator for the type of the object in question: https://source.chromium.org/chromium/chromium/src/+/main:bas...

Re: Please restore our registers when you’re done with them

#110

Earlier quoted context omitted.

Doesn't GCC inline assembly actually track that info, with the "clobber" section?

Yes, but it's not a property of the assembly (or assembler), it's a necessity for the compiler to correctly codegen around the inline assembly. Historically, assemblers have been really dumb, so ABI is not a thing they'd track, especially as... I don't think they know what functions are? So while they can notice call/ret, they have no knowledge of a label being a jump or call target per-se, do they? So you'd need an…

I think most assemblers know what functions are. There are usually directives to indicate this. They help with emitting symbols (you need the function name to be emitted or no-one can call it), stack unwind information, and other information (some of which may also be required by the ABI). Here's some relevant documentation for MASM https://learn.microsoft.com/en-us/cpp/assembler/masm/proc?vi...

The short version of it is that assemblers these days are rarely - if ever - just a zero-context stream of machine instructions. There is far more, some of it actually required.

Post reply on HN