From Black Box to Blueprint: AI-Assisted Legacy Reverse Engineering - Thiyagu Palanisamy
About this talk
This talk explores the reverse engineering of legacy systems that lack source code, emphasizing the need for a fresh perspective on modernization. The speaker discusses common pitfalls in legacy system modernization, highlighting that technological shortcomings are often not the main issue; rather, it's the understanding of the system's functionality that matters. By observing system behavior, inferring business intent, and validating through various methods, teams can transition from viewing systems as black boxes to gaining functional clarity. The session outlines a structured approach using observations and available data to rebuild confidence in outdated systems and to accelerate forward engineering. Techniques such as capturing user interface elements and tracing database changes are discussed to understand system interactions. The importance of creating a context library is highlighted, suggesting that future reverse engineering efforts can leverage these frameworks effectively.
Full transcript
Today I'm going to focus on the talk is more or about like how do we reverse engineer legacy system which doesn't have a source code. So the crux is more around like how do look at the system in a different perspective rather than like just looking at as a legacy system I need to have a code and I need to have access to it, right? So instead
of looking at like see it in a different perspective which will help us to move from a legacy to a something meaningful and from that meaningful how we can fast track the forward engineering part of it, right? So just to unpack the structure how I'm looking at this more in terms of like why generally the legacy modernization fails, right? And move on to what is a new
way of thinking about it and getting into the approach and getting into the details of how exactly you can do something. And more what does how does this unlocks, right? So that's the how I have structured the session and feel free to stop me at any point in time. one of the I think the legacy system when it comes, most of the modernization doesn't fail just because
of a technology, right? So the technology of the old system or a new system it's not about the technology it is about the understanding of the system. So as long as we don't really understand what we are rebuilding, we will not be able to rebuild, right? So if you look at the modernization of the systems many of the failure happens during the early phases, right? So most
of the teams get into analysis paralysis of like trying to build the confidence, try to understand that hey what all my system does, right? So typical to the legacy nature is that the system has been in the existence for couple of decades and the team which have built would have long moved on and nobody would be able to confidently say that hey uh this is something is
what the system does, right? So, not having that confidence is the key factor where we have seen most of the failures are coming from. And one of the system uh we attack to us more in terms of like uh the system uh which has been used by more than 50,000 internal and external users. Uh so, heavily being used and it has been uh yeah, typical to any
uh legacy systems, right? So, what you will see is that system does many things. So, what that means that that system has been integrated to most of their core systems in the background and uh they have made multiple attempts to actually uh modernize the system and they have failed. Uh and the yeah, obvious part is that uh they have lost the source code to the system as
well. And that was the starting point for us to uh actually uh look at like how do we uh un- unblock the system and move forward with forward engineering, right? So, our goal was uh actually the creating a functional specification which will help us to do a clean state. Uh the functional specification more so from the confidence perspective. Like uh it's not doesn't matter like whether we
create a complete functional specification or not. If we are not confident, we will never be able to give that confidence to the uh person who is responsible for uh the business unit who are responsible who are using the systems, right? So, we need to build uh confidence as a team which doesn't have any access to the SMEs, doesn't have access to the source Uh then ensure that
we are able to transfer that confidence to the uh customer, right? So, that's where we started with. And I'm sure like with the many of the sessions and uh lot of you guys who've been involved on the AI from the forward engineering perspective, right? So, it's lot more easier. You can get lot more productivity when you define the task, when you have a specific outcome what you
want to the AI, you would be able to move forward. Similarly, from the reverse engineering perspective, if you have the code, it's again another kind of challenge, right? So, how do you manage that to move forward? But here, the challenge is that without the source code, how did we accelerate and move forward? So, that's what I'm going to share. our approach revolves around that, like don't look
at the legacy systems as black boxes. They are basically observable systems, right? So, first, observe the behavior, observe the system behavior. Then the second thing is like infer the intent, infer more in terms of like what is the business intent, what business really wanted to do. And if you look at the legacy system, one of the thing is the system is doing something, but what it really
encapsulates is that the business would have evolved over a period of time, right? So, it has the history of the business evolution. It would have the history of the process changes. It would have like if you just look at the code or if you just look at the system in isolation, you're going to get lost in that, right? So, instead, focus on like observe the system and
then understand the business intent. Once you understand or interpret the business intent, try to validate that, like you could do the cross validations in terms of like different layers or you could do the cross validation with respect to the the human in the loop validation, right? So, I will go into the details of it. at a high level, this is what we follow, like observe, infer, and
validate the system. This gave us like a from a black box system to a functional understanding of what does the system do, and then we could confidently rebuild the system. Uh as yeah, spoken more about the black box, right? Yeah. >> The black box we talked uh Yeah, literally source code is lost. So, we only had the runtime. Yeah, that's the the slider stayed about the system
in discussion like it started in late 1990s. It was in the evolution for like probably for decade or so. After that, the system lived only in virtual machine. Basically, the last team which did the the changes, somehow they managed to create a virtual machine and had it over to the our clients and they rolled off. And from then on, the team which was maintaining that, they didn't
had anything else apart from like they can just replace a VM if something goes wrong. They can bring back the copy of the VM. They can't do anything else, right? So, what we had was more in terms of like the UI. It's a three-tier web application to the classic uh 2000 era, So, it had a ASP and JavaScript. So, we could get some static screenshots and the
JavaScript information. The database, we could access the database, so we could get the schemas and we could get the stored procedures and could do a limited CDC on that. The key was the middleware. We didn't had the code base completely. It was only a DLL which was configured in the system which was running. So, that was the only thing we had. So, we have to remap the
end-to-end flow with these information. Yeah, so just to connect the dots, our overall approach is more in terms of like looking at like available data sources, whether it is static or a dynamic information, right? So, ASP codes or stored procedures or user interface exploration by AI. So, getting all these data sources, we convert it into semi-structured one. And using this semi-structured data brought in the checkpoint with
the SME. So, it goes back to the loop of like until we are confident that this part of the functionality is good. This goes back into this loop, right? So, once reached a threshold where we feel confident, then we will take it forward to the forward engineering where uh it goes into two parts. So, the same specification we'll use it for creating the test harness and as
well as creating right? So, so that we can keep verifying the what system we are building and the tests are also getting generated while we are building the system. Well, this is the end-to-end flow we have been following with respect to the complete AA accelerated reverse engineering and forward engineering Uh but, in this talk, I'm going to focus more around AA accelerated reverse engineering for now. just
to double click, right? So, these are the available data sources we had like we had the screenshots, ASP and JavaScripts, and we had like type lib definitions extracted from the DLL. And then we had the stored procedure data schema. So, somewhere we These are the signals we have got like from the signals we inferred like what it could be the intent and then we created the functional
summary at a high level, right? So, getting into the specifics of uh example, right? So, from a UI layer perspective, what we have done is we looked at from the screenshot uh we could understand Sorry, it's not visible like each of the UI elements we were able to determine that okay, what those UI elements are. From there, we're able to link them to be what are the
actions which was happening associated to that, right? And then the dynamic behavior and we also continuously as in when we were determining each of the UI elements, we were also building the traceability so that at any point in time we can do the cross-check of this. Uh, so, uh, if you look at it like, uh, from tracing, then adding, uh, the, uh, what are the actions which
are happening, right? So, if you look at like, for every UI element, right? So, it is like, uh, it's in codes the validation, it encodes the workflow, and it you also have the business constraints, right? So, look for like, what are those information, where it is being hidden. This will give you the, uh, starting point to say that, what when user does something, what is happening behind
the scenes, right? then the next thing what we did was the data change. Uh, so, I think this is one of the most important thing for us more in terms of like, probably if you don't have the code, data changes are the most reliable part of the systems, right? So, if you are able to observe like, when you do uh, what happens, what are the side effects,
or what is the effect which happens on the system, right? So, it could be on the database, it could be on the file system, or it could be on, uh, yeah, the downstream system. If you are able to, uh, trace that, and if you are able to like, hey, I do this, and these are the tables getting impacted, right? So, if you are able to for each
of the action connect the dots, then you would be able to start building the perspective on that, hey, what is actually the system is doing. Uh, then like, yeah. I think this is where we started building the confidence with respect to, what is happening, right? So, uh, look at like, we had no clue about that system, and we just had access, limited access to the system, to
that one of the VMs, and we have to, uh, actually, uh, recreate the system from there. And for us, the every step, we wanted to build the validation and this is how we started building the validation out of it. And like once we had the information what are the changes happening, then it was more about enriching that information with the schemas and the database stored procedures information,
right? Then we started able to build the bigger picture of that, hey, what is happening on the back end? What is happening on the front end? So this gave us more in terms of at the end of this phase, it is like we know something is missing in the middle, but we know that we are doing first part we are doing something and we are doing uh
we can see that this is what happening in the back end, right? And uh this gave us to create more in terms of inferred what we call it as a inferred server uh layer, right? So to say that server layer the middleware should be doing something like this. And with that we moved on to the actual uh middleware challenge, right? So more in terms of like the
missing middleware problem for us. So we got the UI enriched, we got the database enriched, and what we were missing was the context missing is the the problem started for us more in terms locating the DLL if they didn't had a source control. If they have had, they wouldn't have had this problem at first place, right? What is that means is it created the side effects of
like the same DLL, it had multiple versions. Like the people who would have just copy pasted into the environments to say that hey, this is new, this is the latest, this is the version three, and figuring out what uh being used itself is a challenge to start with, right? So we have to look at the registry to figure out what is happening. And we were dealing with
like uh around 50 DLLs to for each of those DLLs we have to uh really figure out what was happening on um Yeah, you have to go through the registry and ensure that you are uh mapping the right file. And because uh they had uh references and multiple versions going on, like uh it's just it took the hard work. It was not as straightforward to say that,
"Okay, these are the DLLs, too." Yeah, so see, you can get it if it had a debugging information uh embedded in that. Uh so, if you don't have, then it will like if you have created only the uh runtime version uh you won't uh have it. And one of the thing we also noticed was like uh they have uh I don't know if it was uh intentional
or it was not uh by accident, the code has been obfuscated to uh larger extent. So, it was scrambled, so it was made it almost like uh somebody wanted not to reverse engineer the code. So, that was uh one of the other challenge we have faced. Uh so, just to give you uh quick snapshot, right? So, where we started was DLL uh we decompiled it, we got
the assembly code of it. And there are tools which can uh convert it into assembly to C, but what we learned hard way was uh the conversion uh couple of tools what we have experimented, it was uh not doing a good job. So, which means that of the uh parts of it was getting missed out. So, we have to deal with only the assembly code to start
with, right? And again with so many DLLs, the challenges we are facing was more in terms of like the AI context window. So, in the past it would have been nearly impossible to say that, "Okay, I have thousands of lines of assembly code to convert that into what exactly that assembly to doing, right?" So, it would have been months of activity. With uh AI, yeah, we were
able to fast-track that one, but we were facing challenges like the context window, and it was also doing a lot of hallucination. And given that there is no way to verify that what is actually happening over there, uh in many cases, if it hallucinates, for us to really catch that whether it is hallucinating or not is also a problem. So, that's why we have to come up
with the framework of like smaller context window, uh try doing validation multiple levels, uh so that we can understand, the next big challenge was that, okay, yeah, we were able to pass in a smaller snippets and try to bring in, right? But uh we are talking about like probably uh 300, 400 K lines of assembly code. And like looking at all those things just in one DLL,
uh it had like a 4,000 uh methods, right? So, for a 4,000 functions, understanding that what does this functionality do, uh it's almost impossible, right? So, one of the thing which helped us is to more in terms of we started with slicing the system to uh from a business capability perspective uh to say that, "Hey, the system does that 10 different functionality. Out of these 10 different
functionality, let us focus on one functionality." And then started uh going through that like first when we did the more in terms of the change data capture and the UI uh playback, we were able to understand that hey, what tables it is changing and where the changes are going in. Then that gave us a keyword to say that, "Okay, somewhere this table should be there. Somewhere in
the code we should be able to do, right?" So, this is where I mentioned about the obfuscation, right? So, it was not a straightforward one, but we were able to match keyword from the table name and which helped us to say that, "Okay, if this table is being used, uh let's try to walk backwards from the leaf node, right?" Uh so, we know that this table is
updated by this function. Then we looked at like which are its function parents call and parents call. So, we walked the tree and in that process we also have to eliminate. Like there were a lot of different functions which was getting into to call the same thing, right? So, eliminate those things. And one of the key challenge we faced over here is the context poisoning. More in
terms of like the moment we said that, "Hey, uh we are looking for like invoice submission." And then uh it started giving us like every method to say that, "Hey, this looks like uh invoice field validation. This looks submitting an invoice, right?" So, but uh really when we try to cross-check that more from isolated check, we realized that that was not really doing. It was just a
generic functionality. It was just interpreting it as an invoice one, right? So, we have to be very conscious of the context poisoning from that perspective. It's almost like a clean room uh setup you have to do so that you are not letting the AI build on top of like positive reinforcement, right? So, we don't want to get into the positive reinforcement aspect of it. So, once we
looked at that, then like we know we have traced that, "Okay, from the lowermost function." So, we know it's parent and we know it's parent. Then what we started doing was like we did a multi-pass tree walking to enrich the context like the simplest example over here, right? So, say this is a function fun whatever 103. We try to give a meaningful name at first pass to
say that hey, this process and validates an inquiry. And when we did the second pass, we were able to understand a little bit more about like say you have a context about from the child and you move it to the parent and now you have a parent's child's context to parent and you can understand a little bit more about this parent. And when you build the same
context to back to the other function, right? So, then this function can become a little bit more meaningful. And when you come back down the tree, now you are coming with an additional context to the child and similarly to the child, right? So, like that we did a multi-pass to keep validating say what it started as a process and validate inquiry. And at the second pass it
become process request by document details, right? And similarly like what it started as a get shipping request detail. At the end of the third pass we could understand that it is processing a shipping request complete workflow was happening over there, right? So, walking back and forth helped us to strengthen that one. >> This is a good example of what I did the other day. >> Sure. the
121 you did it. I know what are the details of the other >> Yeah, more or less, right? So, if you are looking at it see some of the intermediate challenges that like we couldn't make any change to the system and we had only a limited area to play around. Say if it had to be debugger, if you were able to enable the debugger, the life would
have been a lot more easier. Unfortunately, we couldn't. >> So you said assembly to see, right? Yeah. Through a deterministic approach or was it an A? >> No, like the tools like Ghidra which can help you to decompile the DLLs and it can get into C. Assembly to C, yeah. It's a deterministic tool. But the problem is that the quality of it was it was not so
good. Like it was missing some of the context. That's why we have to ignore that. Just operate based on the assembly code. >> What's that tool? >> Ghidra. So once we did that, like the next challenge we faced was that uh So we know the call stack. We know that okay, these are the methods which was involved in this. This is the area in which the operation
is performing. But where we were we had trouble was finally mapping the actual UI call to the entry point because the virtual table was involved and we were not able to crack open the virtual table. And what we have to do was we have to triangulate in this point in time to say that okay, do a call stack analysis, validate the argument signature in the stack and
actually do the like the return signature. And once if all these comes together and we can confidently say that hey, this must be this function where when the action happened and these are all the parameters being passed and when the call is ended, it is passing in these are the return values back to it, right? So we try to map that way to that. Once this part
is done, pretty much we had the fragments of uh end-to-end to say that hey uh from the UI, from the middle layer, what is happening, and the back end, right? So, this gave us a uh functional summary of uh end-to-end uh submission. And if you look at it in each of these stages, right? So, we continuously did the validation, we did the cross-checking, so that even though
we are not the expert of the system, uh but by doing small piece at a time, building confidence and validating, we were able to confidently go back and say that hey, this is what being done end-to-end. Um one another thing we did as part of this exercise was also to like uh uh create uh test uh automated test one where it can run on the both the
legacy system as well as on the new system and try to mimic the behavior and uh do, right? So, those those are small small things which we did. We try to uh learn from it and ensure that okay, what we have learned is working or not, and uh build on top of it. >> What are we doing statically that you have applied here? Was that the best
option available? But that's not a strong point. Because my client gave another strategy to talk about innocent. But that's the given. >> Thanks. >> So, and you I you use multiple to to to align this UI and the middle layer to the back. >> Yeah. So, see, it is always the uh this is a evolving space, right? So, uh like uh pro this we did like uh
4-5 months back, and probably the LLM output what we are seeing now is much better than what uh we have had uh before, right? And the context window has also uh opened up a lot quite a lot now. And what we have also gone through is more in terms of automating some of this process uh so that it becomes easier for us to like what we started
as a manual process and uh now we are getting into more into automated process with the validation built in so that we can scale this one and that's where we are. >> But uh I thought you said you would observability in both DSP and data lake and tell me when they're that was we were so that they know the pulse type was not getting an offer. So
there is there option of like putting that either the time will click completely data on the other which causes data generality. So I can make whatever action is happening goes through your path. >> everything and then maybe the data will go to another data before collection to get all the signals that's where your tax tax collection is >> Yes, so we applied that also like putting in
a proxy in front of it. So one particular area we had few challenges so we went into the proxy state and we were also looking at like one of the plan plan we had was to track the network traffic as well but we didn't need to get there because even before tracking the network traffic we were able to crack this problem. Otherwise yeah, we would be getting
into So yeah, looking at it right so key takeaways one of the thing people get stuck is more in terms of like legacy system I need a code right so we could do effectively without code by just being observing the system right so observe what is happening in the system and uh what matters is more about understanding the behavior like putting ourselves in the shoes of business
users right so what they really look at is they look at like is the system performing what intend to do right and if we can decode the same way then it becomes a lot more easier for us and like where this is going into more and more is like you reverse engineer the system, create the context libraries, and once you have the context libraries, then you it
will be lot more easier for you to recreate the systems, right? So, on demand. And this is where we see more and more like what we started 6 months back and where we are now, right? So, the reverse engineering work happening on this more around like, "Hey, I want to build my own context, right?" So, I want to build my context library, whether it is with source
or without source, right? Uh so, what we clearly see is that probably in the next 2-3 years uh more than like whatever than the last 20 years, how many systems have been retired, right? So, probably in the next 2-3 years more than that a lot of system would be uh sunset because of the power of the LLMs what we are seeing today, right? So, the simple the
uh assembly code if we have to reverse engineer, probably we would have taken months, and uh I could get that done in not even uh minutes, right? Within few minutes I could do. But, the crux is that like bringing up these frameworks, bringing up these uh how do you build that framework which will give you as a trustable uh reverse engineer is the key. Uh it's not
just using the uh uh LLM or a tool uh perspective, Uh I don't know how many of you are uh using LLMs today to do the reverse engineering. Good. Quite a lot, right? So, yeah. I think one of the advice I've been uh giving to anybody is more in terms of like uh start small even if you can start like don't wait for a perfect moment, right?
So, uh what you can uncover in days, uh I'm uh that will challenge your notion of like, "Okay, this is an untouchable system, right?" So, this is a very uh brittle. All those things you would be able to change if you are uh just create a sandbox and uh attempt for even a small experiment will uncover a lot for you. >> Yeah, but you published a white
paper you experience to this uh reverse engineering wrong. Uh based on your understanding and telling that perfectly I'm going to do most of the work. >> Yeah, I do have like I have published this in Martin Fowler's uh site. Uh if you look at the black box reverse engineering, uh I have detailed it out there and Martin Fowler. >> For sure there'd be a lot of path
that the people through this space and come down to the detail again. Yeah. True. And like when when all the Yeah. You want me to talk? Yeah. >> I was thinking you know what is the best strategy to apply to various technology reverse engineering like some some related to another. The way I was thinking is that example if you take Selenium and take the application and prepare
all the test case. Use the test cases to build your implementation. Then complete your middle layer and the UI. You know that will explain getting the job done. >> That's simple talk to me. >> Yeah, so you could observe you could build that. The challenge is more in terms of like the moment you uh look at the system at the topmost level, the creating the permutation combination
uh combination with becomes the challenging, right? So uh typical to the uh test pyramid. >> Still a problem. I don't know I was thinking like it's not that we running you look at it we did not go into the source. Instead uh source. >> Looked at the assembly to take and move forward, right? >> Part of you still relied on the source. >> That is the that's
the thing. If the source were there, it would have been much faster. >> It would have been completely yeah. >> The challenge here was to more like de-compiling and then understanding the >> Still the what the insight that you guys gathered was at the source level? in most cases monetization would start at the zero point would be source of that you You Yeah. >> Like minus here.
>> Did not give it up. >> Yeah. And like see even with the source right so what we have found more and more is that like probably you would have more than 60 70% of the source code would be absolute right? That functionality is not being used and things like that. Tracing out like if you try to reverse engineer the entire application the ROI of reverse engineering
gets challenged if the applications usage is only very limited >> How did you address the validation part with the cost regarding to the work on the top clinical development of the site? >> Twist that gap of domain expertise to verify the code given to you that outcome. >> Okay. Okay. So exactly the same problem like we didn't SME or the developers who worked on the system and
what we have to do was for us to build the confidence slicing into a smaller chunk from a business functional perspective helped us to like one we can look from get inputs from the users who are using like what are they using from the perspective. The other thing is we were also bringing in the domain knowledge of that okay this particular area say if it is about
issuing an invoice what are all the common things they would be doing right? And like then try to bring those context and cross validate so that does the smaller piece it's like the building in the Lego blocks right for each block you ensure that that block is good and then start fitting the next block on top of it. >> The domain that this particular client was the
financial or the health care >> kind of retail. It's because the domain of health care and finance could be a different level and the way to >> There you will have a lot more legal challenges well, right? So, the regulatory compliance will come into picture. Yeah. >> Data diff, we put in more like the triggers so that we exactly know the what are the changes has happening.
And Yeah, we interpreted that to say that, "Okay, when say I'm submitting a form, what is happening?" Like it is going and creating these these these and this far field has been validated. Say I have sent it as a string. And some concatenation has happened over there and it is stored at something else, right? Then we were able to map that saying that, "Hey, there is a
conversion happening from here to here." What is that conversion? Then that triggered a research to go and figure out what exactly is that conversion. Yes. Yes. Yes. >> That's it. >> Thank you. Thank you.
More from this event
See all 126 talks →
AI Is Not the Risk. Architectural Drift Is - Sunil Kalkunte
17:39
Breaking the Monolith: Tesco’s Journey to Federated GraphQL with xAPI - Vishwas Chandrashekar
29:13
A Practical Introduction to LangChain4j - Venkat Subramaniam
1:01:28
Beyond the AI Models: How Lowe’s is Building the Store That Knows - Swaroop Shivaram
13:59