Yes, you are right. You do need a separate business object to represent a relationship between two objects that, in addition to linking the objects, also has to capture some additional information. In your case it would be the role of the company on the project and the company representative.
Another approach you may consider, that does not require the additional business object, is to have a separate attribute for each role a company may have on a project. For example, on the Project object you may have attributes Builder, Client and Consultant (multiple values not allowed), all of type Company. Respectively, on the Company object you would have matching attributes ProjectsBuilt, ProjectsCommissioned and ProjectsConsulted (multiple values allowed) of type Project. Then the form for object Project will show each company in a separate cell rather than in a table with other companies. Similarly, the form for object Company will show separate tables for projects where the company was the builder, client or consultant. However, if the number of potential company roles (i.e. the category values) is more than a few, or you want to have a freedom to enter a new role at run-time rather than being constrained by the predefined category values, this approach becomes impractical.
Regardless of which approach you take, Aware IM has a very flexible query mechanism, so you will be able to run queries like show all projects where company ABC was the builder and/or company XYZ was a consultant, etc.
You may have a look at objects Loan or Reservation in the configuration of the Library sample application for an example of a link object (between objects Member and Item) with additional information.