TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

You can't copy code with memcpy

423 pointsby hyperrailover 3 years ago

29 comments

WalterBrightover 3 years ago
In my 1980s version of Empire, all the global variables were kept contiguously in one source file. To save&#x2F;restore the game, it just took the address of the first one, the address of the last one, and blitted it to a disk file, and blitted it back.<p>Very fast &amp; easy.<p>Of course, it broke when COMDATs were introduced.<p>I did a similar thing with my text editor. The colors were configurable. The usual way was to have a configuration file, which the editor would read upon startup. But floppy disk systems were unbearably slow. So what I did was take the address of the configuration data in the data segment. I&#x27;d work backwards to where those bytes were in the EXE file, and patch the EXE file. This worked great!<p>Until the advent of virus scanners, which broke that. Virus scanners hated self-modifying EXE files.
评论 #29735995 未加载
评论 #29734503 未加载
评论 #29739111 未加载
评论 #29736416 未加载
评论 #29761201 未加载
SystemOutover 3 years ago
This reminded me of the old days working in Windows 3.1 and my first professional project was to write a SOCKS client that could be loaded up and intercept all calls to Winsock&#x27;s connect() function. It needed to do this without modifying the other programs and it had to happen at the DLL level and not the VxD layer where our IP stack ran.<p>Turns out there was an undocumented Windows API function along the lines of &quot;AliasCsToDsRegister&quot; or something like that - I&#x27;ve tried to find a reference to it but I can&#x27;t find it. It allowed me write into the code segment (the CS was global and read only - as it was shared among all processes) and replace the first few bytes of the connect function call with a jump to my code which would then put it back, make the call to the socks server, do some other magic, put my jump hook back in and the return to the caller. Good times!<p>Kind of surprised I remember this and more so that it actually worked.
评论 #29734309 未加载
评论 #29735785 未加载
评论 #29735576 未加载
skim_milkover 3 years ago
I remember doing exactly this to get code injection working on GNU&#x2F;Linux systems! I made a library injection library in college for some coursework, which involved copying a C function into a code cave on a remote process and getting the remote process to execute it and return. It only works because its so bare-bones, it doesn&#x27;t use try&#x2F;catch and calls to other functions are possible because the function pointers are passed in through the registers and the compiled code is small enough to fit in a single page.<p>An example function I memcpy and run:<p><a href="https:&#x2F;&#x2F;github.com&#x2F;skimmilk&#x2F;liblibinject&#x2F;blob&#x2F;master&#x2F;src&#x2F;liblibinject&#x2F;external.cpp#L92" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;skimmilk&#x2F;liblibinject&#x2F;blob&#x2F;master&#x2F;src&#x2F;lib...</a>
评论 #29732586 未加载
justiczover 3 years ago
&quot;This code is such a bad idea, I’ve intentionally introduced errors so it won’t even compile.&quot;<p>I am stealing this line.
评论 #29732137 未加载
评论 #29733335 未加载
评论 #29734490 未加载
评论 #29733543 未加载
RcouF1uZ4gsCover 3 years ago
&gt; I pointed out to the customer liaison that what the customer is trying to do is very suspicious and looks like a virus. The customer liaison explained that it’s quite the opposite: The customer is a major anti-virus software vendor! The customer has important functionality in their product that that they have built based on this technique of remote code injection, and they cannot afford to give it up at this point.<p>As an aside, whenever I set up a Windows PC for me or a family member, the first thing I do is uninstall any third-party antivirus that may have come with the computer. I have found that anti-virus software likely makes my computer more insecure by having a big attack surface, not to mention slowing it down.
评论 #29731938 未加载
评论 #29732457 未加载
评论 #29732098 未加载
rwmjover 3 years ago
I think the even crazier thing is Windows having a function to allocate memory in another process (<a href="https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;windows&#x2F;win32&#x2F;api&#x2F;memoryapi&#x2F;nf-memoryapi-virtualallocex" rel="nofollow">https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;windows&#x2F;win32&#x2F;api&#x2F;memoryapi...</a>). That seems like a potential source for all kinds of impossible to track bugs.<p><i>&gt; The customer is a major anti-virus software vendor! The customer has important functionality in their product that that they have built based on this technique of remote code injection, and they cannot afford to give it up at this point.</i><p>Oh now it makes sense.
评论 #29736079 未加载
评论 #29736240 未加载
评论 #29743748 未加载
评论 #29735914 未加载
SeanLukeover 3 years ago
When I took a compiler class back in the early &#x27;90s, the project was to write the compiled machine code into an array, then cast the array into a function, and execute it. I and another student were doing it on 68040 NeXT workstations. One other student was doing it on a Mac, one on a VAX, and the rest on PCs (the PC students largely failed!). We were mystified why, when we tried to execute our code, it was as if it wasn&#x27;t there. Took us a while to realize that the 68040 had separate instruction and data caches, and even more time (and emailing people at NeXT) to determine what the cache flush procedure was.
评论 #29734359 未加载
seligman99over 3 years ago
I wrote a &quot;cd&quot; replacement for cmd[1] a _long_ time ago (I only recently uploaded it to Github).<p>It uses exactly this technique to run a thread in cmd&#x27;s process to actually change the directory. It&#x27;s kept working from XP on up to Windows 11 now. I am always amazed it works, I fully expect it to go boom some day, probably with an error along the lines of &quot;Don&#x27;t do that, please&quot;.<p>[1] <a href="https:&#x2F;&#x2F;github.com&#x2F;seligman&#x2F;ccd&#x2F;blob&#x2F;master&#x2F;RemoteThread.cpp#L416" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;seligman&#x2F;ccd&#x2F;blob&#x2F;master&#x2F;RemoteThread.cpp...</a>
评论 #29737485 未加载
jl2718over 3 years ago
I was competing in the Jump Trading programming competition and thought I had a pretty good implementation in AVX asm, but I was still behind one of their engineers, so I asked him after the competition. Turns out he was a Linux kernel committer and wrote a process to spawn multiple threads by copying itself, modifying the parameters, and then setting the offsets directly in the thread table, avoiding all mallocs and thread startup. So basically, his math code was just basic C loops, but his process was complete before my threads even finished allocation.<p>Forgive me if I got it wrong, I am definitely not a Linux kernel committer.
rkeene2over 3 years ago
This reminds me of the time I wanted to run binaries compiled for SSE3 on a system that lacked SSE3. I started writing a tool to emulate this [0], and one thing it could do is rewrite the executable pages with replacement instructions if there was something that would fit (using memcpy(2), naturally).<p>This harkens back to the days when you could &quot;download&quot; a math coprocessor for your SX system, which was a TSR which likely did the same catching and handling of illegal instructions.<p>[0] <a href="https:&#x2F;&#x2F;github.com&#x2F;rkeene&#x2F;sse3-emu&#x2F;blob&#x2F;master&#x2F;libsse3.c" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;rkeene&#x2F;sse3-emu&#x2F;blob&#x2F;master&#x2F;libsse3.c</a>
评论 #29736966 未加载
fork-bomberover 3 years ago
Memcpying and executing code could also surface micro-architectural realities of the underlying CPU and memory subsystem micro-architecture that may need attention from the programmer.<p>For example:<p>- On most RISCy Arm CPUs with Harvard style split instruction and data caches special architecture specific actions would need to be taken to ensure that after the memcpy any code still lingering in the data cache was cleaned&#x2F;pushed out to the intended destination memory immediately (instead of at the next cache line eviction).<p>- Any stale code that happened to be cached from the destination (either by design or coincidence) needs to be invalidated in the instruction cache.<p>- Depending on the CPU micro architecture, programmer unknown speculative prefetching into caches as a result of the previous two actions may also need attention.
评论 #29735610 未加载
userbinatorover 3 years ago
I&#x27;ve done stuff like this before; it works very well if you know the limitations, and I&#x27;d say that it even gives you a better understanding of how things actually work. Of course, don&#x27;t bother MS or any other &quot;official&quot; vendor if it doesn&#x27;t work, because you are on your own in debugging it.
评论 #29733350 未加载
评论 #29734095 未加载
ouidover 3 years ago
&quot;No, the opposite of a virus, an anti-virus&quot;. Thereby demonstrating that a virus is its own anti-particle.
评论 #29733056 未加载
basementcatover 3 years ago
The client certainly should have made sure their code was truly position independent.<p>Also, the client should have embedded their code in the executable file name so they just have to jump to the appropriate offset in argv[0]. This way, future updates just require renaming the file!
评论 #29735568 未加载
评论 #29736578 未加载
jnwatsonover 3 years ago
At least one additional step which is required on some architectures is you must flush the data cache and invalidate the instruction cache at the location of the new code.<p>Dynamically loading code is indistinguishable from self-modifying code, and each architecture has special steps you must take in order for it to work.
WalterBrightover 3 years ago
&gt; This code is such a bad idea, I’ve intentionally introduced errors so it won’t even compile.<p>No problem, I just fixed the compiler to compile it!
truekonradsover 3 years ago
Much of red-team&#x2F;pentest&#x2F;malware code works like this and is surprisingly reliable.
评论 #29732978 未加载
评论 #29732639 未加载
评论 #29732603 未加载
dark-starover 3 years ago
I actually did something like that on Windows x86, and it worked fine. Even I was surprised by that fact :)<p>I used it to copy out a (forgotten) password from a password inputfield in another program, which you cannot read remotely (for security reasons). Worked fine for that one use-case, and I haven&#x27;t used this trick it anywhere else ever again :)
评论 #29731881 未加载
wmuover 3 years ago
- It looks like a virus... - But it&#x27;s the antivirus!<p>:)
评论 #29732368 未加载
leni536over 3 years ago
Of course all of this is very much undefined behavior in standard C and C++. Some programmers really need to learn that they program the &quot;abstract machine&quot; when they write C or C++.
评论 #29732127 未加载
评论 #29732686 未加载
评论 #29732409 未加载
0xdkyover 3 years ago
I froze for a moment seeing this article after having worked at a major anti-virus company long time back and used some low level Win32 APIs.<p>Fortunately, I followed some of the techniques from “Programming Applications for Microsoft Windows” book and Detours project to intercept and execute custom code mostly based on loading custom DLL in target remote process and using DllMain() to execute.
ggmover 3 years ago
Yet, copy-on-write works well in Unix fork&#x2F;exec() models and helps reduce memory pressure. Presumably, the kernel has a mechanism which presents as logistically simple &quot;copy&quot; but takes care of page&#x2F;pointer&#x2F;vm necessity.
评论 #29733827 未加载
oshiar53-0over 3 years ago
Related: <a href="https:&#x2F;&#x2F;devblogs.microsoft.com&#x2F;oldnewthing&#x2F;20190902-00&#x2F;?p=102828" rel="nofollow">https:&#x2F;&#x2F;devblogs.microsoft.com&#x2F;oldnewthing&#x2F;20190902-00&#x2F;?p=10...</a>
weinzierlover 3 years ago
Isn&#x27;t this whole idea of injecting code on modern systems doomed because of write xor execute (W^X, NX), which is hopefully enabled?
评论 #29735494 未加载
mrlonglongover 3 years ago
Yes, you can copy code with memcpy as long as it&#x27;s position independent code!
donkarmaover 3 years ago
Does anyone else remember reading an Old New Thing article like this one before?
评论 #29737452 未加载
Jyaifover 3 years ago
Don&#x27;t publicly make fun of your customers... unless they are an anti-virus company.<p>What boggles my mind is how they went on to ask MS for help fixing their obviously wrong vulnerability-and-crash-introducing software.
评论 #29732468 未加载
phendrenad2over 3 years ago
As long as the code is truly position-independent, I.E. compiled with -fPIC in GCC&#x2F;LLVM, then there will be no problem.
评论 #29732862 未加载
badrabbitover 3 years ago
Malware authors disagree.