Semantic Designs can construct custom obfuscators for virtually any source language as a part of the corresponding Source Formatter. This page contains Ada sample code, its obfuscated version, and the generated obfuscation map.

Ada Sample Code before Obfuscation


-- GENERAL OPERATIONS ON DIRECTED GRAPHS
   -------------------------------------

-- Creation :  8-JUN-1988


with Stacks,
     Queues;

package body Directed_Graph_Operations is
--------------------------------------

   procedure Graph_Traversal (From      : in Vertex;
                              In_Graph  : in Graph;
                              Order     : in Graph_Traversal_Order;
                              Direction : in Graph_Traversal_Direction) is

      generic
         type Vertex_Storage is limited private;
         with procedure Store (Item : in Vertex; Into : in out Vertex_Storage);
         with procedure Retrieve (From : in out Vertex_Storage; Item : out Vertex);
         with function Empty (Storage : Vertex_Storage) return Boolean is <>;
         with procedure Destroy (Storage : in out Vertex_Storage) is <>;
      procedure Graph_Traversal;

      procedure Graph_Traversal is

         Waiting_Vertices : Vertex_Storage;
         Marked_Vertices  : Vertex_Set;
         V                : Vertex;


         function Adjacent (V : Vertex; In_Graph : Graph) return Vertex_List is
         begin
            case Direction is
               when Forward =>
                  return Succ(V, In_Graph);
               when Backward =>
                  return Pred(V, In_Graph);
            end case;
         end Adjacent;

         use Set_Of_Vertex;

      begin
         Add(From, To => Marked_Vertices);
         Store(From, Into => Waiting_Vertices);
         while not Empty(Waiting_Vertices) loop
            Retrieve(Item => V, From => Waiting_Vertices);
            begin
               Action(V);
            exception
               when others =>
                  Destroy(Waiting_Vertices);
                  Empty(Marked_Vertices);
                  raise;
            end;
            declare

               Adjacent_To_V : constant Vertex_List := Adjacent(V, In_Graph);

            begin
               for I in Adjacent_To_V'Range loop
                  if not Member(Adjacent_To_V(I), Marked_Vertices) then
                     Add(Adjacent_To_V(I), To => Marked_Vertices);
                     Store(Adjacent_To_V(I), Into => Waiting_Vertices);
                  end if;
               end loop;
            end;
         end loop;
         Empty(Marked_Vertices);
      end Graph_Traversal;

   begin
      case Order is
         when Depth_First =>
            declare

               package Vertex_Stacks is new Stacks(Vertex, Count => Natural);

               procedure Traverse_Depth_First is new Graph_Traversal(Vertex_Storage => Vertex_Stacks.Stack,
                                                                     Store          => Vertex_Stacks.Push,
                                                                     Retrieve       => Vertex_Stacks.Pop,
                                                                     Empty          => Vertex_Stacks.Empty,
                                                                     Destroy        => Vertex_Stacks.Destroy);

            begin
               Traverse_Depth_First;
            end;
         when Breadth_First =>
            declare

               package Vertex_Queues is new Queues(Vertex, Count => Natural);

               procedure Traverse_Breadth_First is new Graph_Traversal(Vertex_Storage => Vertex_Queues.Queue,
                                                                       Store          => Vertex_Queues.Put,
                                                                       Retrieve       => Vertex_Queues.Get,
                                                                       Empty          => Vertex_Queues.Empty,
                                                                       Destroy        => Vertex_Queues.Destroy);

            begin
               Traverse_Breadth_First;
            end;
      end case;
   end Graph_Traversal;

end Directed_Graph_Operations;

Ada Code after Obfuscation

(You may need to use your horizontal scroll bar to see it completely). Notice that comments are gone, names have been scrambled, and whitespace has been garbled. Larger constants (none in this example) have their radix twiddled. The obfuscator uses special lists provided by the user to define names that should be preserved, ensuring that public interfaces and accesses to standard packages and public libraries remain valid; we didn't take advantage of that here. If you obfuscate a set of Ada source files simultaneously, only the public symbols they collectively offer will be visible in the compiled source files. An SD-supplied list covers the Standard Ada packages.


with l0,O0; package body l1 is
            procedure O1(l2: in O2; l3: in O3; l4: in O4; l5: in O5) is
            generic type l6 is limited private; with procedure O6(l7: in O2; O7: in out l6); with procedure l8(l2: in out l6; l7: out O2); with function O8(l9: l6) return
Boolean is <>; with procedure O9(l9: in out l6) is <>; procedure O1;
            procedure O1 is
            la: l6;
            Oa: lb;
            Ob: O2;
            function lc(Ob: O2; l3: O3) return Oc is
            begin
            case l5 is when ld => return Od(Ob,l3);
                       when le => return Oe(Ob,l3); end case; end lc;
            use lf; begin
            Of(l2,lg => Oa);
            O6(l2,O7 => la);
            while not O8(la) loop l8(l7 => Ob,l2 => la);
                                  begin Og(Ob); exception when others => O9(la);
                                                                         O8(Oa);
                                                                         raise; end;
                                  declare lh: constant Oc := lc(Ob,l3); begin for Oh in lh'Range loop if not li(lh(Oh),Oa) then Of(lh(Oh),lg => Oa);
                                                                                                                                O6(lh(Oh),O7 => la); end if; end loop; end;
end loop;
            O8(Oa); end O1; begin
            case l4 is when Oi => declare package lj is new l0(O2,Oj => lk);
                                          procedure Ok is new O1(l6 => lj.ll,O6 => lj.Ol,l8 => lj.lm,O8 => lj.O8,O9 => lj.O9); begin Ok; end;
                       when Om => declare package ln is new O0(O2,Oj => lk);
                                          procedure On is new O1(l6 => ln.lo,O6 => ln.Oo,l8 => ln.lp,O8 => ln.O8,O9 => ln.O9); begin On; end; end case; end O1; end l1;

Obfuscated Symbol Cross Reference

The obfuscator produces a cross reference mapping obfuscated symbols to the orginal symbols, so that obfuscated code in the field can still be decoded if necessary. In fact, by reversing this map, the obfuscator can unobfuscate the code (of course, it cannot restore the comments).


### Obfuscated Identifiers ###
Action -> Og
Add -> Of
Adjacent -> lc
Adjacent_To_V -> lh
Backward -> le
Breadth_First -> Om
Count -> Oj
Depth_First -> Oi
Destroy -> O9
Directed_Graph_Operations -> l1
Direction -> l5
Empty -> O8
Forward -> ld
From -> l2
Get -> lp
Graph -> O3
Graph_Traversal -> O1
Graph_Traversal_Direction -> O5
Graph_Traversal_Order -> O4
I -> Oh
In_Graph -> l3
Into -> O7
Item -> l7
Marked_Vertices -> Oa
Member -> li
Natural -> lk
Order -> l4
Pop -> lm
Pred -> Oe
Push -> Ol
Put -> Oo
Queue -> lo
Queues -> O0
Retrieve -> l8
Set_Of_Vertex -> lf
Stack -> ll
Stacks -> l0
Storage -> l9
Store -> O6
Succ -> Od
To -> lg
Traverse_Breadth_First -> On
Traverse_Depth_First -> Ok
V -> Ob
Vertex -> O2
Vertex_List -> Oc
Vertex_Queues -> ln
Vertex_Set -> lb
Vertex_Stacks -> lj
Vertex_Storage -> l6
Waiting_Vertices -> la

For more information: info@semanticdesigns.com    Follow us at Twitter: @SemanticDesigns

Ada Obfuscation
Example