Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
MeNicefellow
@MeNicefellow
Hi, just want to inquire anyone got any idea what is the best solution to convert the cpg.bin to json so that it could be loaded by python?
m1cm1c
@m1cm1c
@MeNicefellow it might be a better idea to export to the dot format: https://docs.joern.io/exporting/
MeNicefellow
@MeNicefellow
@m1cm1c Thanks man.
Anyone got any idea how to get the line number corresponds to a cpg node?
When I use joern-export to export it to dot files.
Alessandro Mantovani
@elManto
Hi! What's the best way to log the results of a query in a file?
Claudiu-Vlad Ursache
@ursachec
@elManto you can use the |> operator, e.g. cpg.method.fullName.l |> "my-fullnames.txt"
Juilia F
@FJuilia_twitter
hey :) i'm trying to distinguish write access from read access. is there a way of finding out whether a specific local variable gets written to? preferably also with some location of where (e.g. which of its identifiers or what call is used)
Claudiu-Vlad Ursache
@ursachec
@FJuilia_twitter it depends what you mean by gets written to. For assignments like x = 2, you can search the graph for CALL nodes with the assignment operator as their method, e.g. cpg.call.methodFullName(Operators.assignment).l. If you're looking for byte-copying stdlib functions with a specific variable as argument, you would search for cpg.call.code(".*strcpy.*").where(_.argument.codeExact("x")) . Other steps from the reference card might be helpful https://docs.joern.io/cpgql/reference-card
Juilia F
@FJuilia_twitter
@ursachec thanks for the ideas. i'm mostly concerned about writes through operators, not through functions that just happen to perform a write. but there are many ways operators can write. i can think of =, +=, -=, *=, /=, %=, |=, &=, ^=, <<=, >>=, var++, ++var, var--, and --var. but there might be more. i think that arrays and structs further complicate things. is there a universal way of detecting writes, at least as far as operators are concerned?
Niko Schmidt
@itsacoderepo
@FJuilia_twitter maybe there is a misunderstanding here. You can do:
call.png
So you can think of the method "assigment". If i stick to the code in the screenshot, it is =(res,crypto_scalarmult((unsigned char *)q, (unsigned char *)n, (unsigned char *)p).
Juilia F
@FJuilia_twitter
@itsacoderepo thanks but i know that operators are implemented as calls. i was wondering whether there is something built-in that finds all calls that definitely perform a write. shortly before you answered, i gave up on finding it and am now using a filter: .filter(node => node.property("NAME") != null && (Array("<operator>.preIncrement", "<operator>.postIncrement", "<operator>.preDecrement", "<operator>.postDecrement").toList.contains(node.property("NAME").toString) || node.property("NAME").toString.slice(0, 21).equals("<operator>.assignment")))
Niko Schmidt
@itsacoderepo

@itsacoderepo thanks but i know that operators are implemented as calls.

Then i misunderstood your question.

operators.png
you can use regex to get the methods you want ^
Juilia F
@FJuilia_twitter
@itsacoderepo oh, thank you for the hint! yes, that's much easier :)
Niko Schmidt
@itsacoderepo
From there you can go to the calls:
joern> cpg.method.name("<operator>.*").callIn.head 
res12: Call = Call(
  id -> 1000882L,
  code -> "--pos",
  name -> "<operator>.preDecrement",
  order -> 3,
  methodInstFullName -> None,
  methodFullName -> "<operator>.preDecrement",
  argumentIndex -> 3,
  dispatchType -> "STATIC_DISPATCH",
  signature -> "TODO assignment signature",
  typeFullName -> "ANY",
  dynamicTypeHintFullName -> List(),
  lineNumber -> Some(value = 189),
  columnNumber -> Some(value = 26),
  resolved -> None,
  depthFirstOrder -> None,
  internalFlags -> None
)
or
joern> val myOperators = List("<operator>.preDecrement", "<operator>.assignment") 
myOperators: List[String] = List("<operator>.preDecrement", "<operator>.assignment")

joern> cpg.method.name(myOperators:_*).name.p 
res18: List[String] = List("<operator>.preDecrement", "<operator>.assignment")
I personally like to create a list of interesting methods at the beginning of a script and use it as "var arg" later on, like myOperators:_*
Juilia F
@FJuilia_twitter
okay, i'll try that :) thank you
Niko Schmidt
@itsacoderepo
np
hyunji-Hong
@hyunji-Hong

hi! I'm a starter of Joern, and I have difficulty connecting Joern server mode. (./joern --server).
I want to connect my VM server(Ubuntu) with my local pc(MacOs). 

(I turn on the joern server in my vm server and try to access the server through python in local PC,MacOS)
But, when I ran my python program, the program failed due to a connection error.

Here are some of the details:

[ip info]
vmware ubuntu(NAT): 172.16.191.2

[error message]
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/asyncio/selector_events.py", line 526, in _sock_connect_cb
raise OSError(err, f'Connect call failed {address}')
ConnectionRefusedError: [Errno 61] Connect call failed ('172.16.191.2', 8080)

[in my python program code]
server_endpoint = "172.16.191.2:8080" //following github(cpgqls-client) example

[More info]
1) I checked vm netstat when I turned on Joern server, and I saw that port 8080 port is open.
2) I checked connection between vm and local PC, and it’s ok(checking through ping)
3) I checked tcpdump in local PC, when local PC access to VM Joern server Port, it returns RST packet, so the connection failed.

So… is there a solution about this issue?

xshub
@xshub
Hi, I want to run a script to extract PDG/AST/CFG and save it to a JSON file by using Joern . I fine-tuning the "graph-for-funcs.sc" of the old version Joern, and it can work. But the result missing a lot of information compared to the result which extracting by Joern Shell Command (e.g. "cpg.method(xx).dotPdg.l").
  val cfgChildren = method.out(EdgeTypes.CFG).asScala.collect { case node: nodes.CfgNode => node }.toList

  // val local = new NodeSteps(
  val local = new Traversal(
    //methodVertex
    method
      .out(EdgeTypes.CONTAINS)
      .hasLabel(NodeTypes.BLOCK)
      .out(EdgeTypes.AST)
      .hasLabel(NodeTypes.LOCAL)
      .cast[nodes.Local])
  val sink = local.evalType(".*").referencingIdentifiers.dedup
  //val source = new NodeSteps(methodVertex.out(EdgeTypes.CONTAINS).hasLabel(NodeTypes.CALL).cast[nodes.Call]).nameNot("<operator>.*").dedup
  val source = new Traversal(method.out(EdgeTypes.CONTAINS).hasLabel(NodeTypes.CALL).cast[nodes.Call]).nameNot("<operator>.*").dedup

  val pdgChildren = sink
    .reachableByFlows(source)
    .l
    .flatMap { path =>
      path.elements
        .map {
          case trackingPoint @ (_: MethodParameterIn) => trackingPoint.start.method.head
          case trackingPoint                          => trackingPoint.cfgNode
        }
    }
    .filter(_.toString != methodId)

  GraphForFuncsFunction(methodName, methodFile, methodId, astChildren, cfgChildren, pdgChildren.distinct)
xshub
@xshub
Why the result is different? Who can provide a new script to extract AST/CFG/PDG and save it to a JSON file . Thanks very much.
xshub
@xshub
@rasmusli_gitlab Hi, I also find the new "graph-for-funcs.sc". Can you share it?
Niko Schmidt
@itsacoderepo
@xshub please check the docs for exporting graphs https://docs.joern.io/exporting
vedkpl
@vedkpl
Hi, al
i have the following snippet:
int 
main(int argc, char *argv[]) {
        int eaten = atoi(argv[1]);
        int value ;

        if (!strcmp(argv[1]), "drink") {
                eaten += 1;
                value = eaten * 3;
        } else {
                value = eaten;
        }   

        return value;
}
i ran the following query:
cpg.returns.l(0).reachableByFlows(cpg.call("atoi")).l
to check the possible flows from atoi() to the return of the function
but the query only lists one path ("if " case flow)
and not the other ("else" case flow)
i expected it to list 2 flows (i.e 2 Paths)
is my query correct?
Niko Schmidt
@itsacoderepo
@vedkpl it seems that we have a bug here
Karan Panjabi
@karanpanjabi
Hello, new to Joern community. I had a doubt and I was wondering if anyone could help
I tried running Joern on a toy C++ project with a class which has public and private members. However, while running a query to figure out whether the members are public or private, it just gives an empty List()
hac425xxx
@hac425xxx
image.png
the code
void array_oob()
{
    int user = read_byte();
    global_array[user] = 1;
}
It seem the user (read_byte) flow to global_array (ArrayAccess) is ignore?
which lead to follow query return nothing
def F() = {
    val src = cpg.call.name("read_byte")
    val sink = cpg.call.name("<operator>.indirectIndexAccess").argument.order(2)
    sink.reachableByFlows(src)
}
F.l
Anyway to fix this?