When You Inherit a System With No Source Code and No Documentation — A Practical Playbook for Keeping It Running
· Go Komura · Legacy Technology, Legacy Asset Reuse, Operations & Maintenance, Maintenance, Black Box, Reverse Engineering, Handover, Bug Investigation, Technical Consulting, Windows Development
“The company that built it doesn’t exist anymore.” “The person who built it left and we can’t reach them.” “There’s an executable and a database sitting on the server, but no source code and no specifications anywhere.” This is a far from rare situation in consultations about SME business systems. And yet the system is still running today, and the business still depends on it.
The worst move in this situation is to start poking at it with trial-and-error fixes or offhand environment changes just because “nobody really understands it.” A system with no source code comes with no guarantee that you can fix it if it breaks. On the other hand, jumping straight to “there’s nothing we can do, we have to rebuild the whole thing” is also premature. There are ways to reconstruct a specification even without documentation, and there are cases where you can still read the internals even without source code. This article lays out, in the order you’d actually do it in practice, the steps for getting from nothing at all to a working operations-and-maintenance setup.
1. The Bottom Line First
- The first thing to do is not modification — it’s preserving the current state. The running production environment itself is your most important asset. Take a disk image backup (e.g., turning it into a virtual machine with Disk2vhd) and a database backup, and confirm you can actually restore from them before moving on.1
- You can reconstruct the specification even without documentation. The main materials are interviews with the people who use the system, the screens and reports, the database schema, the logs, and observing actual behavior with Process Monitor.2
- How recoverable the source code is depends heavily on the technology stack. For .NET, decompilers like ILSpy can get you quite far; for native code such as VB6 or C++, realistically you shouldn’t expect to recover much.34
- Decompiling has legal considerations. Article 30-4 of the Copyright Act is understood to permit use for investigation and analysis purposes in principle, but checking the contract (license terms) is essential.5
- Don’t wait until you “fully understand” everything. Prioritize understanding the parts where an outage would stop the business and the parts that are likely to need changes soon, and make changes small, one at a time, and reversible.
- A quasi-mandate contract is the basic model for maintenance. You can’t promise completion liability (a contract for work) for investigating a system whose internals are unknown. Split the contract into an investigation phase and a modification phase.
2. Why Does a “Nothing at All” Situation Happen?
Before thinking about how to respond, it helps to figure out which pattern your own situation falls into — that gives you a sense of what clues might still be around.
| Pattern | Typical history | What often survives |
|---|---|---|
| The development company closed or withdrew | The maintenance contract lapsed, years passed, and contact was lost | CD-Rs from delivery, acceptance records, contracts (sometimes buried in storage) |
| The in-house developer left | One person built it, it became entirely dependent on them, and they left | Fragments of the dev environment or source on that person’s PC or a shared folder |
| Business transfer / M&A | The system was inherited along with the business, but the documentation wasn’t transferred | The inventory list from the transfer agreement, contact routes to people at the former company |
| Source exists but can’t be trusted | Source was found, but there’s no guarantee it matches the running executable | Build timestamps and version info to cross-check |
The last pattern is easy to overlook, but it needs to be treated, in practice, the same as “there’s no source.” A classic failure is treating an old copy of the source as authoritative and modifying it, only to discover the production executable actually had years of fixes baked in that the source never saw. Even if you find a source tree, don’t trust it until you’ve built it and cross-checked the result against the production executable.
Whichever pattern you’re in, it’s worth searching for the contract, delivery notes, and acceptance records first. If copyright ownership or a source-code delivery obligation is spelled out there, it becomes the foundation for any negotiation or legal analysis that follows.
3. What to Do in the First Week — Preserving the Current State and Taking Inventory
3.1 Freeze all changes
Until the investigation is done, the rule is to leave the target servers and machines alone. “Let’s just update the OS for now” or “let’s clean up files that don’t look used” are exactly the kind of thing that can be fatal. With no source code, there is no “just fix it” option if something breaks. It’s also worth considering bringing update timing under control so automatic updates (Windows Update, changes in antivirus behavior) don’t silently alter the environment on their own.
3.2 Backup — duplicate the environment itself as an asset
A file-level backup alone isn’t enough. In this kind of system, the OS settings, the registry, the runtime, and even the deployment location may all be part of “why it works,” so you preserve the entire disk image.
In practice, Sysinternals’ Disk2vhd is the tool most commonly used for this. It can convert a running system, while still online, into a consistent VHD/VHDX using a Volume Shadow Copy (VSS), giving you the foundation for a verification environment you can boot as a Hyper-V virtual machine.1 The advantage is that it lets you address aging physical-server risk and secure a verification environment at the same time (note that OEM-licensed Windows may not be permitted, under its license, to move to a virtual environment, so checking the license type is necessary1).
Alongside that, back up the database using the DBMS’s own standard method. And the single most important step is to actually restore from the backup and confirm it starts up. A backup that has never been through a restore test is just insurance you assume you have. That said, since a restored image still has the production connection settings and scheduled tasks intact as-is, always perform the first boot in an environment isolated from the network (details in Chapter 7). Boot it up while still connected by accident, and what you meant as a test environment can end up updating the production database or its integration partners.
3.3 Inventory — list out everything that’s running
Next, mechanically enumerate the system’s components. This is a job for thoroughness, not intuition.
| Inventory target | How to check | What to look at |
|---|---|---|
| The full set of executables | The install folder, under Program Files | File version, last-modified date, and digital signature of each EXE/DLL |
| Anything that auto-starts | Sysinternals Autoruns6 | Startup entries, services, resident processes |
| Scheduled tasks | Task Scheduler | Nightly batch jobs, monthly/annual processing (check execution history too) |
| Database | Connection strings, ODBC settings | Destination server, schema, whether it’s shared with other systems |
| Configuration | INI files, the registry, app.config, etc. | Paths, connection targets, mode switches |
| External integrations | Shared folders, FTP, outgoing mail, external APIs | The counterparty and direction (importing or handing off) |
| Accounts and certificates | Service account, certificate store | Password and certificate expiration dates (a quiet time bomb) |
If you can’t tell where a config file or output destination lives, observing the process’s file and registry access with Process Monitor is the fastest route — the paths the application is actually reading and writing show up directly in the list.2
4. You Can Reconstruct the Specification Even Without Documentation
Once the inventory tells you “what’s there,” the next step is reconstructing “what it does.” The materials are all available.
- Interviewing the people who use the system — The best specification you’ll find is inside the head of whoever uses the system every day. Walk through daily, monthly, and annual business processes, asking what gets entered on which screen and what comes out. In particular, annual processing (closing the books, year-end inventory, fiscal-year rollover) is something even the person in charge may have forgotten, and it’s a common point of failure the first time around after a handover.
- Screens and reports — Catalog every screen and every report with screenshots and real samples. Just the correspondence between input fields and output fields already reveals much of the skeleton of the processing.
- Database schema and data — Table definitions, constraints, and the actual data behind coded values are fossils of business rules. An observation like “this flag only ever takes three values” tells you about specifications you’d never see from the screens.
- Logs and the event log — Application-specific logs, if they exist, reveal the flow of processing, and the Windows event log reveals past error trends.
- Observing actual behavior — Recording file, registry, and network access with Process Monitor lets you confirm input/output relationships — “this end-of-month process reads a CSV from this shared folder and talks to this database server” — without any source code.2 That said, Process Monitor only shows you who the traffic partner is; it doesn’t show which tables were updated and how. Beyond that point, you need the DBMS’s own tracing/auditing features (such as SQL Server extended events), or comparing database contents before and after a process runs.
What matters here is not trying to document every feature equally. The goal is continuity of operations, not an encyclopedia, so prioritize “processing that stops the business if it stops,” “processing that’s throwing errors,” and “areas that will need changes soon,” building up the ledger of what you’ve investigated from there.
5. What’s Technically Possible Without Source Code
How far you can expect to “read the internals” is largely determined by what the system was built with. Estimate the technology stack from the executable’s properties and DLL composition, and set your expectations accordingly.
| Technology stack | Recoverability of internals | Main approach |
|---|---|---|
| .NET (C#, VB.NET) — regular IL format | High | Decompilers such as ILSpy. Visual Studio itself has a built-in decompilation feature based on ILSpy43 |
| .NET — published as Native AOT | Low (equivalent to native code) | Converted to native code with no intermediate language (IL), so recovering C# via a decompiler isn’t realistic |
| Java | High | Similarly readable via decompilers (it’s also intermediate code) |
| Web systems (scripting languages such as PHP) | Source is often already sitting on the server | It’s well worth checking the server first |
| VB6 | Low | Mechanically recovering something close to the original source isn’t realistic; the focus shifts to behavior-based analysis and partial reimplementation |
| C / C++ (native) | Low (highly specialized) | Disassembly and pseudocode generation are possible but costly; focus on targeted analysis rather than full recovery |
For a .NET app deployed in regular IL format, the situation is quite good — the C# code you get from decompiling is practical enough for understanding the processing. That said, as the official documentation itself states, comments, local variable names, whitespace, and other information not needed at compile time are lost, so it should be treated as a resource for understanding behavior, not a substitute for the original source code.3 There are exceptions too: if obfuscation has been applied, decoding difficulty rises sharply, and a binary published with Native AOT contains no IL, so the assumption “it’s .NET, so it’s readable” doesn’t hold. When assessing the technology stack, check the deployment format as well as the development language.
If a PDB (symbol file) survives alongside the executable, you may be able to recover function names, and even the original source itself if it’s embedded. What a PDB can and can’t give you is covered in “What Is a PDB (Program Database)?”.
Legal considerations — “check first” before decompiling
Being technically able to do something and being allowed to do it are two different things. Reverse engineering, including decompiling, carries copyright-law considerations. Under Article 30-4 of the Copyright Act (newly added in the 2018 amendment, covering “use not intended for enjoying the thoughts or sentiments expressed in a work”), reproduction or adaptation for the purpose of investigating and analyzing a program is understood to be permitted in principle, to the extent found necessary. However, the article includes the proviso that this “does not apply where it would unreasonably prejudice the interests of the copyright holder,” so, for example, using the results of analysis to build a competing product could be assessed differently.5
There’s also the separate contractual question of how to treat cases where a license agreement for packaged software or a deliverable prohibits analysis. Check the license terms of the software in question and the original development contract (the clause on copyright ownership) before doing this, and consult a lawyer if you’re unsure. If your own company holds the copyright to the deliverable, this issue becomes considerably simpler. For how to read that kind of contract, see also “How Should Contracts for Outsourced Development and Maintenance Be Structured?”.
6. Life Support, Wrapping, or Rebuilding
Once you’ve combined the understanding gained from the investigation with the realities on the business side, it’s time to set direction. Here too, the answer isn’t “full rebuild, no question” or “leave it exactly as is, no question” — sort it out with a decision table.
| Option | Where it fits | Main risk |
|---|---|---|
| Life support as-is (freeze the environment, virtualize) | End of use is expected within a few years; almost no change requests | Lifespan of the OS/runtime, reconciling with security updates |
| Wrap and support (leave the core alone, build new peripherals) | The core is stable, and requests concentrate on added input/output or integrations | The boundary layer gets more complex; dependence on hidden behavior in the core remains |
| Partial rebuild | Change requests concentrate on specific features | Maintaining consistency between old and new; dual data management |
| Full rebuild | Many change requests; the business itself has changed; the cost of life support has flipped | Missing hidden specifications; the burden of parallel operation and migration |
The deciding factors are these four: remaining years of use, the frequency and concentration of change requests, the business impact if it stops, and the level of understanding recovered during the investigation. Moving to a full rebuild with a low level of understanding risks missing the old system’s “nobody can explain it, but it’s the correct behavior for the business” quirks. Even if you choose a rebuild, the ledger of specifications reconstructed in Chapter 4 becomes the basis for your requirements definition, so the investment in investigation is never wasted. At migration time, the standard approach is to run the old and new systems in parallel for a set period and mechanically cross-check the output (reports, aggregates, files) for the same input.
For technology-specific life-support and migration decisions, “Life Support and Migration for VB6 / Access Business Apps” covers VB6 and Access in detail, and “A Guide to Breaking Free of IE-Mode-Dependent Systems” covers internal web systems dependent on IE mode.
7. Operating and Maintaining It After the Handover
If the direction is “keep operating it for the time being” — which, in practice, describes most cases — sticking to the following patterns cuts down on accidents.
- Have a verification environment — but always isolate the first boot from the network — Booting the disk image you created in 3.2 as a virtual machine gives you a verification environment matching production’s configuration. But that image still has production connection strings, credentials, scheduled tasks, and auto-start services intact. Boot it while connected to the network and you risk a nightly batch running twice and updating the production database, emails being resent, or external APIs being called. Always perform the first boot with the virtual NIC removed or on an isolated network, stop the scheduled tasks and auto-start services, rewrite the connection targets for testing, and only then allow connectivity for the scope you actually need.
- Make changes one at a time, in a reversible way — Whether it’s a configuration change or applying a Windows Update, do one thing at a time. Keep the image from before the change, and roll back if something goes wrong. Pair this with a record of what was changed (a change log).
- Grow the documentation as a byproduct of investigation — Rather than launching a project to write the perfect specification, add to the ledger whatever you learn each time you respond to an incident or make a change. Run it for a year and the documentation fills in, starting from the parts that matter most to the business.
- Build in monitoring — Uptime monitoring, disk space, error logs, and detecting “the file that’s supposed to come out every time didn’t come out.” Even if you can’t see inside the black box, you can monitor its inputs and outputs.
- Split investigation and modification into separate contracts — When outsourcing maintenance, you can’t promise completion liability for investigating a system whose internals are unknown, so it’s healthy to split the contract by phase: investigation and maintenance as a quasi-mandate, and individual modifications, once the specification is settled, as a contract for work (or an outcome-based quasi-mandate).
8. Summary
- If you inherit a system with no source code and no documentation, preserving the current state comes before any modification. Take a disk image (e.g., with Disk2vhd) and a database backup, and confirm you can actually restore them.
- Take inventory of the executables, auto-start items, scheduled tasks, configuration, integration partners, and accounts to build a full picture of the system.
- The specification can be reconstructed from user interviews, screens, reports, the database schema, logs, and observing actual behavior with Process Monitor. Prioritize the parts with the biggest business impact, not every feature.
- How recoverable the internals are depends on the technology stack. .NET is quite readable via decompiling, but it’s not a substitute for the original source. Check the intent of Article 30-4 of the Copyright Act, plus license terms and contracts, before proceeding.
- Decide between life support, wrapping, partial rebuild, and full rebuild based on remaining years of use, frequency of change, business impact, and level of understanding. Whichever path you choose, the specification reconstructed during the investigation becomes an asset.
- In the operations phase, the basic pattern is a verification environment, one change at a time, a change log, monitoring the inputs and outputs, and a quasi-mandate contract.
Related Articles
- What Is a PDB (Program Database)? — Understanding Debug Info, Symbols, and Source Link
- A Practical Guide to Process Monitor
- Life Support and Migration for VB6 / Access Business Apps — A Keep / Wrap / Replace Decision Table
- A Guide to Breaking Free of IE-Mode-Dependent Systems
- How Should Contracts for Outsourced Development and Maintenance Be Structured? — Quasi-Mandate vs. Contract for Work, per IPA’s “Model Transaction and Contract”
- Things to Sort Out Before Outsourcing Windows App Development
Related Consulting Areas
Komura Software LLC handles current-state investigation of business systems with no surviving source code or documentation (analysis of executables, databases, and observed behavior), reconstructing specifications from behavior, sorting out a life-support-versus-migration strategy, and the operations and maintenance that follow. We also welcome consultations starting from “I don’t even know where to begin.”
- Legacy Asset Reuse & Migration Support
- Modification & Maintenance of Existing Windows Software
- Bug Investigation & Root Cause Analysis
- Technical Consulting & Design Review
- Contact
References
-
Microsoft Learn, Disk2vhd v2.02 (Sysinternals). On being able to convert a running system, while still online, into a point-in-time-consistent VHD using Windows’ volume shadow copy feature; being able to attach the resulting VHD to a virtual machine such as Hyper-V and boot it; that it must not be attached for boot purposes to the same system it was created from; that BitLocker-enabled volumes are not supported; and that P2V migration of OEM-licensed Windows may not be permitted under its license. ↩ ↩2 ↩3
-
Microsoft Learn, Process Monitor (Sysinternals). On it being a tool that can monitor file system, registry, and process/thread activity in real time. Practical usage is covered on this site in “A Practical Guide to Process Monitor.” ↩ ↩2 ↩3
-
Microsoft Learn, Generate source code from .NET assemblies while debugging. On Visual Studio’s decompilation feature being based on the open-source ILSpy (Visual Studio 2019 16.5 and later); on the generated source code not being identical to the original because information not needed at compile time — whitespace, comments, local variable names — is lost, and that it should be used to understand behavior rather than as a substitute; on decompilation of the async/await pattern sometimes being incomplete; and on only C# being generated. ↩ ↩2 ↩3
-
ILSpy (icsharpcode/ILSpy). An open-source .NET assembly browser and decompiler. Referenced from Microsoft Learn’s documentation as the foundation for Visual Studio’s decompilation feature. ↩ ↩2
-
e-Gov Law Search, Copyright Act (Act No. 48 of 1970) (Japanese), Article 30-4 (use not intended for enjoying the thoughts or sentiments expressed in a work). One of the flexible limitations on rights put in place by the 2018 amendment; use for the purpose of investigating and analyzing a program is understood to be permitted under this provision, to the extent found necessary. Separate consideration is needed for the exclusion under the article’s proviso — “where it would unreasonably prejudice the interests of the copyright holder” — and for the effect of an analysis-prohibition clause in a license agreement (see also: Uchida & Same-jima Law Offices, “Whether Reverse Engineering of a Program Is Permitted (the 2018 Copyright Act Amendment)” (Japanese)). ↩ ↩2
-
Microsoft Learn, Autoruns for Windows (Sysinternals). On being able to comprehensively list programs registered at Windows auto-start points such as startup entries, services, and scheduled tasks. ↩
Related Articles
Recent articles sharing the same tags. Deepen your understanding with closely related topics.
Incident Response Doesn't End at Recovery — A Postmortem (Recurrence Prevention) Template for Small Development Teams
Treating an incident as over once it's fixed and apologized for guarantees you'll repeat it. This article translates the blameless postmo...
Safely Modifying a Legacy Business App That Has No Tests — Characterization Testing and Refactoring in Practice
To safely modify a business application with no tests, this article explains, with C# examples, the procedure for a characterization test...
How Long Will VB6 Apps Keep Running? — Runtime Support Status and a Practical Path to .NET Migration
How long will VB6 applications keep running? This practical guide clarifies the asymmetry between the VB6 runtime support policy (still s...
Windows App Outsourcing and Contract Development: What to Sort Out Before You Ask
Before commissioning Windows app outsourcing or contract development, here is how to sort out existing software modification, device inte...
An Introduction to ADRs (Architecture Decision Records) — The Minimal Way to Record 'Why We Designed It This Way' on a Small Team
Code never explains why it was written that way. We cover how to use an ADR (Architecture Decision Record) — one decision, one Markdown f...
Related Topics
These topic pages place the article in a broader service and decision context.
Windows Technical Topics
Topic hub for KomuraSoft LLC's Windows development, investigation, and legacy-asset articles.
ActiveX Migration
Topic page for staged decisions around keeping, wrapping, or replacing COM / ActiveX / OCX assets.
Bug Investigation & Long-Run Failures
Topic page for intermittent failures, communication diagnosis, long-run crashes, and failure-path test foundations.
Where This Topic Connects
This article connects naturally to the following service pages.
Windows App Development
We support Windows desktop applications that involve resident processing, device integration, operational logging, and maintainable structure.
Bug Investigation & Root Cause Analysis
We investigate difficult production issues such as intermittent failures, long-run crashes, leaks, and communication stoppages.
Frequently Asked Questions
Common questions about the topic of this article.
- Can I still ask for maintenance or modifications on a system with no source code?
- Yes, you can. The approach just changes from ordinary maintenance. The realistic path is to first preserve and back up the running environment, then set up an investigation phase that reconstructs the specification from the screens, reports, database, logs, and executables, and only then move into modifications or new peripheral development within the understanding gained during that phase. Because an investigation cannot promise its outcome in advance, it's usually run under a quasi-mandate contract rather than a contract for work that carries completion liability.
- Is decompiling an executable (reverse engineering) illegal?
- Not uniformly. Under Article 30-4 of the Copyright Act, newly added in the 2018 amendment, uses that are 'not intended for enjoying the thoughts or sentiments expressed in a work' — such as investigating and analyzing a program — are understood to be permitted in principle, to the extent found necessary. That said, the article carves out cases that 'unreasonably prejudice the interests of the copyright holder,' and there remains the separate question of what happens when a license agreement prohibits analysis. Check the license terms and the original development contract before doing this, and consult a lawyer or other specialist if you're unsure.
- The development company went out of business and I can't get the source code. What should I do?
- Start by checking past contracts and deliverables. If the development contract specifies who owns the copyright and whether source code delivery was required, that gives you grounds for obtaining or using it. If you can reach anyone who was involved, it's worth exploring whether they'll hand it over. In practice, though, it's important not to get stuck on 'we couldn't get it after all' — assuming you won't be able to obtain it, it's worth starting in parallel on preserving and backing up the running environment and reconstructing the specification from behavior and the database.
- There's no documentation at all. Where do I even start?
- Before any modification, start by preserving the current state. Take a disk image of the running production environment and a database backup, and confirm that both can actually be restored. Next, inventory the executables, auto-start items, scheduled tasks, configuration, external integrations, and accounts to build a complete picture of the system. From there, the standard approach is to interview the people who actually use it and observe the screens, reports, and database schema, documenting the specification only for the parts that matter most to the business.
Author Profile
Profile page for the article author.
Go Komura
Representative of KomuraSoft LLC
Focused on Windows software development, technical consulting, and investigations into failures that are difficult to reproduce.
Public links