uh hi I'm Sims Lego vardos I'm a PhD included at the University of Athens and I'll be presenting our paper on ellipse which is doing work with Neville Gray Elia satiris and my advisor Janis moragadakis and we all also work at didop doing program analysis for the ethereum space now ethereum is a programmable blockchain meaning that smart contracts which are small programs can be deployed on it and these programs run on the low level bytecode of the ethereum virtual machine uh most of these are written in high-level languages and solidity is by far the most popular language and because these contracts are deployed on the blockchain and everyone can interact with them and there's a their nature is often financial and generally great there's generally a high need for security guarantees so we need to use all the tools we have to to ensure that these contracts are safe and not hacked so some background on ethereum virtual machine it's a stack based VM and it doesn't have any information on available so we need to resolve this the stack operations use it operates only on 256-bit numbers so they're in desert so there's no type of information all other types are supported with low level operations as well it doesn't have any abstractions for public functions or private ones uh so every Everything uses the same stack basically and to support this the exam targets of the basic blocks can be dynamic so I'll show an example of that later I'll explain that better and also because uh the code is depending on the blockchain and stays there uh compilers have a strong incentive to reduce the deployed code size so they use low level blocks whenever possible now if the ethereum virtual machine is so low level one may ask why don't we then that's analyze solidity source and there are many reasons why that is Impractical as well so most contracts don't have the shortcut available although the the more why the more used ones and the most popular protocols do public to have the social public and major solid releases include breaking changes which is always a problem and popular projects can use solidity versions that can be from 0.4 to 0.8 and one would need support all of this and as also as shown by the previous talk a widespread use of inline assembly means that source code tools need to model the low level intricacies of the AVM and also the solid signal pilot sometimes uh in order to support or many behaviors so that's a problem as well now let's look at a simple smart contract uh the con the contract looks like a class you know Victorian programming now we have one field and that field is stored on the on the blockchain and in our case it's the owner field there's a Constructor which sets the owner field to whoever initialize the contract and an external method which is able to be called by anyone but only allows the owner to withdraw a funds from that congrat in addition because the owner field is public there will be a gather for that as well so it's a pretty simple contract but compiling it looks like this now it's trivial to go from the compiled version to this assembled version which is that and as we said the contract has a single entry point so in order to support the public function entries we need some low-level code and this next block just does exactly that uh the entry point is decided based on the first four bytes on the transactions payload so this uh this block does exactly that it loads the first four bytes and takes them against a known signature has which is how this is done now well I'll talk more about this later we can see another block which pushes to jump destinations to the stack and jump to one of them but leave the stack with the other some destination on it which is also important and I'll talk about more but for that later and we have another blog which we can see that when looked at initialization we cannot really we cannot see what its Target will be what this next block is so these are the dynamic examples I was talking about earlier and they are used very often to support code reuse and we need and these make the compilation tough so we need to model this now let's give our definition of the compilation so we Define the compilation as the recovery of a structured intermediate representation a three other spot in our case from very low level byte code now so what we need to do is we need to infer the variables that the stack of operations use we need to produce a conversional graph and we also identify private functions in reduced code segments and codes are used in other ways so one would ask that don't we already have tools for that academic or otherwise now the most popular academic tool is gigahertz which is from a Nixie 2019 paper but it has its problem so it doesn't scale to large contracts because contracts have gotten exceedingly large as we as time went on and the ethereum ecosystem progressed its output can be often a precise and it makes many mistakes when Infinium function boundaries and the argument and return argument number so it can end up putting blocks in wrong functions now now we present ellipmode which is actually Giga course 2.0 it has been under continuous development since the original publication it's open source and available on GitHub and we use it at ddub as a subset for all our analysis and we have the compiled the compiled and analyzed or contracts from the ethereum and fandom blockchains now I'll give a brief overview of the common pipeline of element and gigahertz and then talk about uh where we made some changes to that now first we get the bytecode we disassemble it identifying the basic log boundaries then we perform a basic a simple local which means Block Level in our case stack analysis so we produce Block Level summaries for the effects each block has on the stack we identify static and dynamic jumps and we also identify the public entry points now after this point we use the information from the local analysis to perform a global control flow graph and stack analysis now for this the meaning of this is to resolve the targets of the dynamic jump statements and to do to do that in a precise manner in order to because we don't attempt to actually execute the contract we attempt to over approximate all its behaviors using context sensitivity in our case and this allows us to separate the different uses of the same block for different paths and then with [Music] after we have this Global control flow graph we go on to the next session try to infer private functions and then after we have that we generate our three address code I intermediate presentation now the output of our three address code looks like that so we can you can see that we have a result variables statements to the variables they use and the ones defined uh but it's still rather low level but it's a good uh representation to have analysis on and also something interesting here is that uh you can say that we have a code reuse we have private functions even in this small gate so this function is a gated for the storage field now what are our main contributions here we introduced a new contact sensitivity model a transactional contact sensitivity which is designed after the execution of smartphone transactions we and I'll get into more of that later and we also did some major improvements to the functional reconstruction logic we designed it and we made a we made it context sensitive and past sensitive in cases in order to strive with balance between precision and scalability now a notable client we have a on ellipmode is a source and particle because when someone thinks of the compilation we don't often think of what we Define as the compilation we also need the client that produces something that is more easily understandable by humans and how we do that is we take the output of Philip mock that's the address code we use some libraries that are available in on our GitHub for inferring high level instructions in memory and Storage and then we list this into an AST presentation we perform simplifications on that and we get the compiled source now the output of that for this particular contract looks like that so you can see we have the two public methods on the left and on the right it's the function selector logic which choose which chooses the correct public function for the contract when we use it for completeness in our output now it's a simple gonna show our uh the compilation output looks very close to what is uh The Source what generally do a good job now I'll get the international contact sensitivity a little bit more so uh the recent digital publication had a call site or a better name would be jump site in this case conduct sensitivity algorithm and we replace it with a domain specific one that is composed of two parts now the first one is a a sticky public function context component which essentially means that we keep the the entry point of the contract the transactional entry point for the whole execution and then we have a component that is parameterizable and contains the and most recent likely function goal or likely function return size now we use heuristics for this because we cannot have a ground rule for that so the likely function called sides are blocks that leave the stack with other jump lists on it and the likely function return sites are the dynamic jumps I talked about earlier so if we go back to our assembled example uh the the first one is a code that finds a public function entry point which we keep the second one of the highlighted ones is a likely function call that what altruistic detects as a likely function call and it's important for us and the third one is likely function return now what's important is that this do not always correspond to actual calls and returns and the control flow is often much more complicated so we can have like continuations where we can go from a return to another return or from a return to another Call Etc so these are just an approximation and in practice we've seen that it's a good model for conduct sensitivity now we have an example here for an execution now we have basic blocks on the left and on the right there's a Legend So this block can either be single blocks public function entries likely function entries likely function returns and that actually so the Bold arrows are the ones that we keep in our model of conduct sensitivity so let's take the this execution on the left we can see that we enter through the public function entry and this is some information that we keep throughout the whole execution but then the next few jumps our analysis does not keep them in we give some information about them but not in our contact sensitivity for the global analysis and then you can see that close to the bottom we read some likely function call with here to this entry which we remember and then after another jump which we don't remember a return as well now in this case we have a transactional competency of the depth of two so we only remember these two blocks now this and is not always good because for example if there were seven different paths to to reach these two blocks from the same public function we would match the information about all this together which can lead that can lead to us having a Precision but it's uh something we are willing to live with and uh jump set sensitivity as in developers would try to remember everything up to its designated depth as well which often uh keeps information that is not really important now I will not get into I will not get into the changes we made to the function reconstruction mods but you can check out the paper I'll just mention the key points now we add support for optimized recursive call patterns and with that context sensitively so we have we try to keep all the information conduct sensitively and get the most out of our Global analysis for our private function reconstruction one then we normalize control flow which was a problem that diggers had and we find blocks that are shared between different pilot functions and clone them to each one of them so that's an improvement and we have a past sensitive argument and return argument inference algorithm now for evaluation we evaluated the element against two tools the one is gigahertz which is it's predecessor and this was a very easy comparison because these two tools serve their core so this allowed us to make a very deep point-to-point comparison then we compared against panoramics which is the leading industrial the compiler it is used by etherscan which is the most popular block Explorer for ethereum and it's a very different tool it is based on simple execution it doesn't produce a control flow graph or any structured IR really it produces a source like output just like our social and parser so we need to come up with high level metrics so for comparing against Giga course uh we did it at a few points like these are some of them in the paper we have more we use the gigahertz ellipmoc and a second invocation of element which uses the same contact sensitivity as gigahorse and this helps us so and understand which of the benefit comes from the conduct sensitivity and what comes from the better the private function influence algorithm now the first thing we have is unstructural control flow so unstructured control flow is basically at the output level of our analysis patterns that cannot be translated to high level control flow of a public of a of source code now and the we can see that for gigahertz in at least 47 of the contracts the compiled by all tools we have this problem where in ellipmoc we only have it in 8.8.8 percent now as we can see using the middle uh bar in this graph the main benefit came from the better private function inference algorithms now polymorphism Target is in Precision at the global analysis level which basically means that under the same context we can you have more next blocks we can see that gigahertz and the context since the US has this problem in close to that nine percent of contracts so it's a so it shows that our contact sensitivity is much more precise and looking at timeouts uh gigaforce times out in 18.7 of the contracts while elephunk times out in under five percent of the contracts and you can see that this benefit comes again from the international content sensitivity so it's both more precise and it has a much more condensed information so it's it allows us to be far more scalable now getting into these scalability numbers in in more depth uh we can say that so what we did here is we we blocked the contracts into uh we split them into some classes based on their size and we so how well a contract does this tool does it success rate for these different sizes now what we see here is that for larger context sizes they conducts other over 15 kilo kilobytes to up to 20 kilobytes can decompile 86 percent of them where gigahertz can only compile 42 percent of them and for contracts over 20 kilobytes a liquid and decompile 89 of them were so we are far more scalable in realistic contracts and that's important because as the ecosystem becomes more mature contracts because and Optima and compilers optimize more contacts we can become harder to decompile and analyze now for comparing against paramix We compare the output of our social parser client with that of panoramics and we have to choose some very high level contract level and high level metrics so what we did was we chose the number of unique external called signatures so the signatures to calls to external cause made inside the contract and the number of unique event signatures inside the contract as well now uh we don't need to look into this in a few detail but what I need to mention is that we used two different invocations of panoramics the one was with uh is a default with the same timeout as we gave development and we use the partial invocation of parameters as well with with which allows it to time out for certain public functions and continue if that if it fail for them and for that we gave it uh 2.5 times the timeout of uh Elite Mock and it still didn't manage to scale as well and we can see that ellipmuk is both more complete and more scalable than paramix and we also go into those we analyzed the we provide numbers for the intersection of contracts at both of these tools analyzing we can see that uh panoramic text 10 times more more time and is less complete now we perform the same experiment to get into the scalability in more depth and we can see that a parallel mix has a similar Behavior to that of gigahertz and it it is way more unscalable for larger contracts so we've used the elite mock to build several research tools on top of it the first one is ethanther a smart conduct security analyzer for compost vulnerabilities which was presented in pldi 20 and will also be presented tomorrow at 4 30 at seminar Loom lg004 are Loops at 20 people on the precise static modeling of memory and arusa 21 paper on the symbolic symbolic value flow static analysis which will be presented at 12 at today at seminar room lg004 again uh something that is worth mentioning that we've we've used the element to perform three studies for the ethereum foundation assessing the impact of some uh protocol changes to all deployed contracts and these are EIP 1884 AIP 3074 and a future size that's proposed to change the gas system of ethereum to use vertical trees and we also use it on a contract on conduct libraries Watchdog Watchdog to perform security analysis and these have gotten as seven High impacts vulnerabilities [Music] in popular protocols so thank you for your attention okay we have a lot of time for questions yeah go ahead cool thanks um nice talk um so I actually had I think it's a simple question um because you said you know obviously control flow can be quite unstructured and does get quite complicated but I'm interested in particular in whether or not um bytecode generated from the solidity compiler is much more structured and easier to decompile versus arbitrary bytecode I mean we don't often see Arbiter bytecode most of it is way less and we don't really know you know what is what other thing there is because there are some contracts where they sound they look like uh it doesn't come home with the compiler but they don't have the source code available so we cannot really understand but these are very few and what I think is that they are contacted make heavy use of inline assembly and someone starts from something that is uh generated by the solid compiler and then to exit by hand to [Music] uh to to be more optimized or whatever but we I don't really have so sorry just trying to so if we imagined a contract solidity contract with no inline assembly compiled using optimization with the solidity Commander that is not the hardest kind of code to decompile oh no it it is still hard it's very hard yeah okay thank you thanks for your presentation so you as you have shown you have a lot of intermediate steps in your analysis uh do you have apis that expose these intermediate results in a way that is really uh convenient and makes it possible for other analysis tools to build on this or you mentioned some cases of other analysis tools to build on it but there's this kind of um uh at the end stage or is it a very internal integration or are you moving towards maybe um sort of standardized interface for say exposing the control flow structure to uh other analysis tools that then other people might build uh we don't really have an API for that but what we have is the source code so everyone can run gigaforce and get the the IR we we produce and also use some other libraries now we we don't have the source like a code available like the The Source the compiler available but for the for The Limited representation for analysis it's all there it's on GitHub so that's what we have available yeah maybe uh going a little bit beyond your topics but uh if you look at the at the scalability result table again it wasn't really a uh uh clear dependence of course clearly dependent on the sizes no not yet this one yes yes so I was I was curious about the the remaining 10 beyond that 20 kilobyte is that all the sheer size or what can you elaborate on what makes you unable to decompile certain contracts okay so for article right for for help yes yes of course yeah it's uh mostly cases where something in our analysis becomes unscalable so some patterns perhaps where we have our abstraction for context can end up producing many contexts in many inferences that are not perfect so have some scalability there and also the private function inference is which takes that the condo sensitivity can also be can also become very unscalable and sometimes because it tries to be path sensitive it tries to infer lots of information Conde sensitively so this is the main reason yes uh yeah this is a very nice work uh thanks for the talk actually I wanted to ask uh so uh can you go back to the slide where you show the different basic blocks uh with the edges yeah yeah this one so over here uh so when you say this is a likely private function entry right uh so how many of these uh so how many of these do you consider when you are like constructing the control flow graph like so how do you figure out that okay I I mean like these are the blocks and the function like or these are the possible jumps that are happening so the we consider all of them basically it's very similar heuristic and that heuristic is that any block that looks like the middle one there that pushes another at least attack with another jump destination push to it we consider it to be a possible call and for our connectivity this is a possible call so we don't we don't try to bind that okay so uh in case if there are functions that are like uh so can it happen inside the byte code where like functions are sharing blocks between them or block support between them so in that case how do you like construct the control program for let's say a particular function uh what we do is we basically like after we figure out that a Blog is part of more than one function we clone the blocks in in both functions so can it so happen that uh like when you are cloning uh like can the context change like I mean the things that are there in the stack like so how do you fix that in the function uh so can it so happen that uh like each of the functions uh like do you check that the stack contains like the same elements like when you are cloning the blocks I do not understand the question sorry so let's move this offline all right yeah yeah I think I'll probably take it off yeah okay [Applause]