PDA

View Full Version : Orpheu: Searching for functions in libraries


joaquimandrade
02-15-2010, 20:49
A library is a set of bytes. Millions of them. They can represent numbers, functions (in machine code), arrays, strings. This tutorial will try to explain how to find functions in libraries so you can use them.

Finding a function means locate its position in the library. What is normally called offset. It's the number of bytes that it takes to reach the function starting at the first byte of the library.

In libraries compiled by gcc (linux) offsets are labelled with symbolic names with which you can easily recognize what is located at that offset.

In libraries compiled by VC++ there aren't almost no labels so you have to resort to techniques like searching for strings in the library. That because you can easily relate strings to events like, if you see "Terrorists Win" being used you know that you are dealing with a function related to the round end.

Developing over this, the techniques we can use are:


Finding functions by searching strings.
After having found a function use it to find more functions like: if you know that a function calls yours or if yours calls another.
Apply the steps above recursively :twisted:

To make the process easier you should do this with the help of the linux library.

So, grab the libraries of your mod for windows and linux.
Get "IDA Pro Disassembler" (not free).

For each library:

In IDA:

http://img208.**************/img208/8749/12820721.png

Press New

If linux library:

http://img694.**************/img694/1284/37280226.png

If windows library:

http://img684.**************/img684/5552/cenasx.png

Locate the library and open it.

Press Ctrl + F5. This will open a dialog so you can chose where you want a file to be saved. This file is the decompiled version of your library (a feature of IDA that converts machine code back to C code (far from readable code and not exactly resembling the original but easier to inspect than machine code)).

In the decompiled version of the linux library you will have code like:

//----- (000B3C10) --------------------------------------------------------
int __cdecl InstallGameRules()
{
int result; // eax@2
int v1; // eax@2
int v2; // eax@3

(*(void (__cdecl **)(_DWORD))&g_engfuncs[156])("exec game.cfg\n");
(*(void (**)(void))&g_engfuncs[160])();
if ( *(float *)(gpGlobals + 20) == 0.0 )
{
v2 = __builtin_new(708);
result = __18CHalfLifeMultiplay(v2);
}
else
{
v1 = __builtin_new(728);
result = __17CHalfLifeTraining(v1);
}
return result;
}This is the function InstallGameRules where you can easily see the string "exec game.cfg\n" being used.

Now, searching it on the decompiled version of the windows library you can see:

//----- (10088530) --------------------------------------------------------
int __cdecl sub_10088530()
{
long double v0; // fst7@1
int v1; // eax@2
int v3; // eax@4

dword_101623DC("exec game.cfg\n");
dword_101623E0();
v0 = *(float *)(LODWORD(dword_101625B8) + 20);
if ( v0 == 0.0 )
{
v1 = (int)operator new(0x2E8u);
if ( v1 )
return sub_100C5EF0(v1, v0);
}
else
{
v3 = (int)operator new(0x2D0u);
if ( v3 )
return sub_10093D80(v3, v0);
}
return 0;
}From observation you can easily see that you are dealing with the same function (with the bonus of being the only place where the string is located).

This means that at the offset 88530 in the windows binary of Counter Strike we have the function InstallGameRules. You can see that in the function pseudo-label "sub_10088530" (ignoring the sub_10). Since this number represents an hexadecimal number let's call it 0x88530.

Know to demonstrate the other technique let's search in the linux decompiled version of the library for InstallGameRules to find calls to it:

//----- (0011163C) --------------------------------------------------------
int *__usercall CWorld__Precache<eax>(long double a1<st0>, int a2)
{
unsigned int v2; // edi@8
__int16 v3; // fps@15
long double v4; // fst6@15
char v5; // c0@15
char v6; // c2@15
char v7; // c3@15
int v8; // eax@16
int v9; // ecx@18
int v10; // eax@19
int *result; // eax@25
int v12; // [sp-10h] [bp-58h]@16
float v13; // [sp-Ch] [bp-54h]@16

g_pLastSpawn = 0;
g_pLastCTSpawn = 0;
g_pLastTerroristSpawn = 0;
(*(void (__cdecl **)(_DWORD, char[4]))&g_engfuncs[240])("sv_gravity", "800");
(*(void (__cdecl **)(_DWORD, char[4]))&g_engfuncs[240])("sv_maxspeed", "900");
(*(void (__cdecl **)(_DWORD, _DWORD))&g_engfuncs[240])("sv_stepsize", "18");
(*(void (__cdecl **)(_DWORD, _DWORD))&g_engfuncs[240])("room_type", "0");
if ( g_pGameRules )
__builtin_delete((void *)g_pGameRules);
g_pGameRules = InstallGameRules();You can see in the last line that the function InstallGameRules is called from CWorld__Precache (real name CWorld::Precache), so getting back into the decompiled version of the windows library:

Replace all ocurrences of sub_10088530 by InstallGameRules. Search for InstallGameRules.

int __usercall sub_100DD350<eax>(int a1<ecx>, int a2<esi>, long double a3<st0>)
{
int v3; // ebp@1
int v4; // eax@3
int v5; // esi@4
int v6; // eax@6
int v7; // ecx@7
int v8; // eax@8
signed int v9; // esi@17
int v10; // eax@28
int v11; // ecx@29
int result; // eax@33
float v13; // [sp-4h] [bp-10h]@25
signed int v14; // [sp-4h] [bp-10h]@31

v3 = a1;
dword_10162EFC = 0;
dword_10163D00 = 0;
dword_10163D04 = 0;
dword_10162430("sv_gravity", "800");
dword_10162430("sv_maxspeed", "900");
dword_10162430("sv_stepsize", "18");
dword_10162430("room_type", L"0");
if ( dword_10162304 )
operator delete(dword_10162304);
dword_10162304 = (void *)InstallGameRules();And we just found out CWorld__Precache (offset 0xDD350)

This is basically it. By applying this knowledge and your brain you can find almost any function.

Missing then are the types that the function use. You can check them by seeing the list of functions in the linux version of the library in IDA window Names. For the return type I don't know if there is simple way but you can always guess or check half life sdk when it makes sense.

For this case:


{
"name" : "InstallGameRules",
"library" : "mod",
"return" :
{
"type" : "CHalfLifeMultiplay *"
},
"identifiers":
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : 0x88530
}
]
}This should now go into a file named InstallGameRules into the folder configs/orpheu/functions. (Remembered that if the function belonged to a class you would have to create a folder with the name of the class).

Know there is a thing. This offset is guaranteed to be always the same each time the library loads but that can easily not be true if the library gets updated. That's the reason that motivated the creation of a technique called signature scanning (http://forums.alliedmods.net/showthread.php?t=37115).

Signature scanning basically means: instead of provide an offset, provide a set of bytes that you can find at that offset (that represent the function). That set of bytes can easily have its location changed but as long as it exists as a block you can still search for it.

You can find more about that here (http://wiki.alliedmods.net/Signature_Scanning). I might make an easier tutorial for it later.

ConnorMcLeod
02-16-2010, 01:03
Another tut !!!
Any free software that can do the same job ?

wrecked_
02-16-2010, 01:19
From what I looked up about the program, it said the program was ~$500 USD. Is that the cheapest it gets?

*Restate Connor's Question*

01101101
02-16-2010, 04:17
Download the free version.

joaquimandrade
02-16-2010, 07:51
I have here in my pocket a free machine code decompiler that does this but I preferred doing the tutorial with this one.

No, I don't know of a free one. Search it by yourself and stop asking.

Doubts about the tutorial are welcome.

ConnorMcLeod
02-16-2010, 12:13
Doubts about the tutorial are welcome.

Ofc it is !

Doc-Holiday
02-16-2010, 14:17
What exactly can you do with that though

Or is that how ark is going to remove clamps on cvars?

Immortal_BLG
02-21-2010, 00:52
How to possible to view the decompiled code in IDA pro free?

Arkshine
02-26-2010, 05:57
You can't, since the decompiler is not included.

Doc-Holiday
02-28-2010, 09:09
You can't, since the decompiler is not included.


how much is that pro version? i havent looked into it yet.

Arkshine
02-28-2010, 09:57
Search it by yourself and stop asking.

AntiBots
03-07-2010, 05:59
I have IDA Pro Advance 5.6 if someone want to decompiler something :P

Seta00
05-08-2010, 17:42
I have IDA Pro Advance 5.6 if someone want to decompiler something :P

Yeah, you and everyone else who knows how to use ThePirateBay...

The application has been completely decompiled.


By the way, I've got Host_ServerShutdown, anyone can confirm this is valid?

Arkshine
05-08-2010, 18:22
if nothing is returned, you don't need to specify it, you should remove it.

Lt.RAT
05-08-2010, 18:23
By the way, I've got Host_ServerShutdown, anyone can confirm this is valid?

Know there is a thing. This offset is guaranteed to be always the same each time the library loads but that can easily not be true if the library gets updated. That's the reason that motivated the creation of a technique called signature scanning.

Signature scanning basically means: instead of provide an offset, provide a set of bytes that you can find at that offset (that represent the function). That set of bytes can easily have its location changed but as long as it exists as a block you can still search for it.

If you want to use it somewhere, you should provide signature. Also, not sure about your offset.

Also, as i understand, if we have args and ret with void type, we should remove it from our file.

ADD: oh ye, there is no tutorial about writing signatures atm :(

Arkshine
05-08-2010, 19:55
For me, Host_ShutdownServer is : 0x50050

and the sig would be :


{
"name" : "Host_ShutdownServer",
"library" : "engine",
"identifiers" :
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : [0x55,0x8B,0xEC,0xA1,"*","*","*","*",0x85,0xC0,0x0F,"*","*","*","*","*",0x56,"*","*","*","*",0x6A,0x01]
},
{
"os" : "linux",
"mod" : "cstrike",
"value" : "Host_ShutdownServer"
}
]
}


If I'm motivated I will do a tutorial, it's not that hard.

Seta00
05-09-2010, 08:30
For me, Host_ShutdownServer is : 0x50050

and the sig would be :


{
"name" : "Host_ShutdownServer",
"library" : "engine",
"identifiers" :
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : [0x55,0x8B,0xEC,0xA1,"*","*","*","*",0x85,0xC0,0x0F,"*","*","*","*","*",0x56,"*","*","*","*",0x6A,0x01]
},
{
"os" : "linux",
"mod" : "cstrike",
"value" : "Host_ShutdownServer"
}
]
}


If I'm motivated I will do a tutorial, it's not that hard.

Thanks. Guess hacking Orpheu's source won't help me to use it :grrr:

atomen
07-27-2010, 12:13
It might be better for me to do this in a separate topic but I'll let that rest for now.

Detecting shoot event properly requires a bit to much code for my taste therefore
I've been looking for an alternative (orpheu). Now I need some help.

I've found the shoot event offset (EV_HLDM_FireBullets) function name in windows.
Source Code Location: "cl_cll.proj / ev_hldm.cpp (Ln 353)"
Library & Location: mp.dll ("cstrike/dlls")
Function name: sub_19024C0
Hex Location: 0x24C0 (correct me please)Now my question is; do I have enough data to provide myself with an orpheu function, and if so, I would be very pleased with some assistance.

EDIT: If someone wants the EV_HLDM_FireBullets declaration header:void EV_HLDM_FireBullets(int idx, float *forward, float *right, float *up, int cShots, float *vecSrc, float *vecDirShooting, float flDistance, int iBulletType, int iTracerFreq, int *tracerCount, float flSpreadX, float flSpreadY)
EDIT 2: In my bold attempt creating a JSON file for the firebullets function I've might come up with something usable. Inspect and give judgement!
{
"name" : "EV_HLDM_FireBullets",
"library" : "mod",
"arguments" :
[
{
"type" : "int"
},
{
"type" : "float *"
},
{
"type" : "float *"
},
{
"type" : "float *"
},
{
"type" : "int"
},
{
"type" : "float *"
},
{
"type" : "float *"
},
{
"type" : "float"
},
{
"type" : "int"
},
{
"type" : "int"
},
{
"type" : "int *"
},
{
"type" : "float"
},
{
"type" : "float"
}
],
"identifiers" :
[
{
"os" : "windows",
"mod" : "cstrike",
"value" : 0x24C0
},
]
}

Arkshine
07-27-2010, 12:56
Forget, you can't hook it because Orpheu doesn't support some type like int * or float *.

By the way, there is already an accurate method to hook properly shot event. Look at the VEN tutorial. It hooks the events. The example est for CS but it's just a matter to change the event name you can find on your server.

atomen
07-27-2010, 13:14
I see. Though with further research I've discovered this function:Vector CBaseEntity::FireBulletsPlayer ( ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker, int shared_rand )It is located in "dlls/combat.cpp". Is it possible to hook this function with Orpheu?

And yes, I am aware of VEN's tutorial.

EDIT: About my previous post, is it possible to hook the function without the parameters, if that is the problem? Just to use the event

Arkshine
07-27-2010, 13:26
I remember Quim saying "Vector" (without *) can't work. By the way, about your first example, you can't hook client-side functions with a server-side plugin...

What's wrong with the VEN's method ?

drekes
03-10-2011, 14:32
I've tried to search for InstallGameRules too, and the offset matches with yours,
but mine doesn't have the "exec game.cfg\n" string in it.
Did i do something wrong ?


//----- (000B3C10) --------------------------------------------------------
int __cdecl InstallGameRules()
{
int result; // eax@2
int v1; // esi@1
int v3; // eax@2
int v4; // eax@3

v1 = *(_DWORD *)((char *)loc_1326EB + 746809);
(*(int (__cdecl **)(char *))(v1 + 156))((char *)loc_1326EB + 512685);
(*(int (**)(void))(v1 + 160))();
_EAX = **(_DWORD **)((char *)loc_1326EB + 744429);
__asm
{
fldz
fld dword ptr [eax+14h]
fucompp
fnstsw ax
}
if ( BYTE1(_EAX) & 0x44 ^ 0x40 )
{
v4 = __builtin_new(0x2C4u);
result = __18CHalfLifeMultiplay(v4);
}
else
{
v3 = __builtin_new(0x2D8u);
result = __17CHalfLifeTraining(v3);
}
return result;
}

Arkshine
03-10-2011, 14:37
Don't know. What IDA version you're using ? What you show me happen when it fails to decompile properly. Though you don't need to decompile, the string should appear in the IDA View tab.

drekes
03-10-2011, 14:40
I'm using version 5.2.0.908.
I've tried to decompile it several times, but always end up with that code.

Arkshine
03-10-2011, 14:42
You may try to open the binary with different options or try a newer version. (Like 5.5, what I'm using). You can also try to open the CZ binary or the CS binary (with hlbeta update), it's compiled differently, so there is a chance IDA handles it differently too.

drekes
03-10-2011, 15:23
I've downloaded version 5.5 and did everything over.
Now the function matches, and i also saw the string in the other function from the signature tutorial.
Thanks

Arkshine
03-10-2011, 15:34
You are a pro now. :P

meTaLiCroSS
03-11-2011, 13:03
You are a pro now. :P

2012

hlstriker
04-07-2011, 21:14
I decompiled the .so for TFC and I'm trying to understand a function.

In the code below how would I know that victim + 32 is the players X velocity? I'm guessing 32 is an offset but where would I look to figure out what this offset belongs to?
velocity1 = *(float *)(*(_DWORD *)victim + 32) * 0.3300000131130219;
velocity2 = *(float *)(*(_DWORD *)victim + 36) * 0.3300000131130219;
velocity3 = 0.3300000131130219 * *(float *)(*(_DWORD *)victim + 40);

In this part of the code I'm guessing it's a function being called but I'm not sure what's going on. Can someone explain to me?
(*(void (__cdecl **)(int, int))(*(_DWORD *)(victim + 1136) + 260))(victim, concEnt);

I mainly want to figure out how to find the function/variable that belongs to an offset.

Arkshine
04-08-2011, 00:16
- Yes, an offset, but probably more related to entvars_s structure, so it should be a pev->something.

- Probably a virtul call. To know what function it is, I guess you need to find the vtable of the related class. (CBasePlayer? CBasePlayerItem ? etc..). To get the index from this virtual call, it should be : 260/4 - 2 = 63. So the 63th in the vtable list should be your function. (Like hamdata.ini).

For both, what functions ? I will take a look.

hlstriker
04-08-2011, 00:58
Thanks Arkshine,

I'm wondering though how do you know to subtract 2 in "260/4 - 2"?

The function is: CBasePlayer__TeamFortress_TakeConcussionBlast .

Arkshine
04-08-2011, 12:04
/4 because an offset is always scaled by it's data type, since I don't know much C++ I can't explain well, but here each virtual call address is based on 4 bytes.
-2 because you have to that in linux :p, when you look at IDA, you see it starts by 2 offsets before the real list starts.

I've decompiled fastly the function CBasePlayer::TeamFortress_TakeConcussionBlast ().
It may not exact and vars may not named properly but you get the idea.
So yes, it's was pev->velocity and the virtual call TeamFortress_Concuss().


CBasePlayer::TeamFortress_TakeConcussionBlast ( entvars_s *pVictim, float blast )
{
if( IsAlive() && pev->playerclass )
{
Vector direction = pev->origin - pVictim->pev->origin;

if( direction.length() < 16.0 )
{
pev->velocity *= 0.33;
}

pev->velocity *= ( blast - direction.length() * 0.5 ) * 0.03;
pev->velocity.z *= 1.5;

if( !( gpGlobals->teamplay & ( 1<<4 | 1<<3 | 1<<2 | 1<<1 ) ) || m_iTeamIndex <= 0 || IsAlly( CBasePlayer::Instance( pVictim ) || pVictim->>owner == edict() )
{
MESSAGE_BEGiN( MSG_ONE, gmsgDamage, NULL, ENT( pev ) );
WRITE_BYTE( 0 );
WRITE_BYTE( 0 );
WRITE_LONG( 512 );
WRITE_COORD( pVictim->origin.x );
WRITE_COORD( pVictim->origin.y );
WRITE_COORD( pVictim->origin.z );
MESSAGE_END();

TeamFortress_Concuss( pVictim );

CBasePlayer* owner = CBasePlayer::Instance( pVictim->owner );

char* teamName;
char* ownerTeamName;

if( m_iTeamIndex )
teamName = GetTeamName( m_iTeamIndex );
else
teamName = "SPECTATOR";

if( owner->m_iTeamIndex )
ownerTeamName = GetTeamName( owner->m_iTeamIndex );

UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Concussion_Grenade\" against \"%s<%i><%s><%s>\"\n",
STRING( pev->netname ),
GETPLAYERUSERID( edict() ),
GETPLAYERAUTHID( edict() ),
teamName,
STRING( owner->pev->netname ),
GETPLAYERUSERID( owner->edict() ),
GETPLAYERAUTHID( owner->edict() ),
ownerTeamName
}
}
}


Here the vtable list of CBasePlayer :


// Auto reconstructed from vtable block @ 0x00163240
// from "tfc_i386.so", by ida_vtables.idc
0 ___11CBasePlayer
1 CBasePlayer::Spawn(void)
2 CBasePlayer::Precache(void)
3 CBaseMonster::KeyValue(KeyValueData_s *)
4 CBasePlayer::Save(CSave &)
5 CBasePlayer::Restore(CRestore &)
6 CBasePlayer::ObjectCaps(void)
7 CBaseEntity::Activate(void)
8 CBaseEntity::SetObjectCollisionBox(void)
9 CBasePlayer::Classify(void)
10 CBaseEntity::DeathNotice(entvars_s *)
11 CBasePlayer::TraceAttack(entvars_s *,float,Vector,TraceResult *,int)
12 CBasePlayer::TakeDamage(entvars_s *,entvars_s *,float,int)
13 CBasePlayer::TakeHealth(float,int)
14 CBasePlayer::Killed(entvars_s *,entvars_s *,int)
15 CBaseMonster::BloodColor(void)
16 CBaseEntity::TraceBleed(float,Vector,TraceRes ult *,int)
17 CBaseEntity::IsTriggered(void)
18 CBaseMonster::MyMonsterPointer(void)
19 CBaseEntity::MySquadMonsterPointer(void)
20 CBaseToggle::GetToggleState(void)
21 CBasePlayer::AddPlayerItem(CBasePlayerItem *)
22 CBasePlayer::RemovePlayerItem(CBasePlayerItem *)
23 CBasePlayer::GiveAmmo(int,char *,int,int *)
24 CBaseToggle::GetDelay(void)
25 CBaseMonster::IsMoving(void)
26 CBaseEntity::OverrideReset(void)
27 CBaseEntity::DamageDecal(int)
28 CBaseEntity::SetToggleState(int)
29 CBasePlayer::StartSneaking(void)
30 CBasePlayer::StopSneaking(void)
31 CBaseEntity::OnControls(entvars_s *)
32 CBasePlayer::IsSneaking(void)
33 CBasePlayer::IsAlive(void)
34 CBaseEntity::IsBSPModel(void)
35 CBaseEntity::ReflectGauss(void)
36 CBaseEntity::HasTarget(unsigned int)
37 CBaseEntity::IsInWorld(void)
38 CBasePlayer::IsPlayer(void)
39 CBasePlayer::IsNetClient(void)
40 CBaseEntity::DB_GetItemName(void)
41 CBaseEntity::GetNextTarget(void)
42 CBaseEntity::Think(void)
43 CBaseEntity::Touch(CBaseEntity *)
44 CBaseEntity::Use(CBaseEntity *,CBaseEntity *,USE_TYPE,float)
45 CBaseEntity::Blocked(CBaseEntity *)
46 CBaseEntity::Respawn(void)
47 CBaseEntity::UpdateOwner(void)
48 CBasePlayer::FBecomeProne(void)
49 CBaseEntity::Center(void)
50 CBaseEntity::EyePosition(void)
51 CBaseEntity::EarPosition(void)
52 CBasePlayer::BodyTarget(Vector const &)
53 CBasePlayer::Illumination(void)
54 CBaseEntity::FVisible(CBaseEntity *)
55 CBaseEntity::FVisible(Vector const &)
56 CBasePlayer::EngineerUse(CBasePlayer *)
57 CBaseEntity::Finished(void)
58 CBaseEntity::TeamFortress_EMPExplode(entvars_ s *,float,float)
59 CBasePlayer::TeamFortress_CalcEMPDmgRad(float &,float &)
60 CBasePlayer::TeamFortress_TakeEMPBlast(entvar s_s *)
61 CBaseEntity::TeamFortress_EMPRemove(void)
62 CBasePlayer::TeamFortress_TakeConcussionBlast (entvars_s *,float)
63 CBasePlayer::TeamFortress_Concuss(entvars_s *)
64 CBaseMonster::HandleAnimEvent(MonsterEvent_t *)
65 CBaseMonster::Look(int)
66 CBaseMonster::RunAI(void)
67 CBasePlayer::ShouldFadeOnDeath(void)
68 CBaseMonster::ChangeYaw(int)
69 CBaseMonster::MonsterThink(void)
70 CBaseMonster::IRelationship(CBaseEntity *)
71 CBaseMonster::MonsterInit(void)
72 CBaseMonster::MonsterInitDead(void)
73 CBaseMonster::BecomeDead(void)
74 CBaseMonster::StartMonster(void)
75 CBaseMonster::BestVisibleEnemy(void)
76 CBaseMonster::FInViewCone(CBaseEntity *)
77 CBaseMonster::FInViewCone(Vector *)
78 CBaseMonster::CheckLocalMove(Vector const &,Vector const &,CBaseEntity *,float *)
79 CBaseMonster::Move(float)
80 CBaseMonster::MoveExecute(CBaseEntity *,Vector const &,float)
81 CBaseMonster::ShouldAdvanceRoute(float)
82 CBaseMonster::GetStoppedActivity(void)
83 CBaseMonster::Stop(void)
84 CBaseMonster::CheckRangeAttack1(float,float)
85 CBaseMonster::CheckRangeAttack2(float,float)
86 CBaseMonster::CheckMeleeAttack1(float,float)
87 CBaseMonster::CheckMeleeAttack2(float,float)
88 CBaseMonster::ScheduleFromName(char const *)
89 CBaseMonster::StartTask(Task_t *)
90 CBaseMonster::RunTask(Task_t *)
91 CBaseMonster::GetScheduleOfType(int)
92 CBaseMonster::GetSchedule(void)
93 CBaseMonster::ScheduleChange(void)
94 CBaseMonster::CanPlaySequence(int,int)
95 CBaseMonster::CanPlaySentence(int)
96 CBaseMonster::PlaySentence(char const *,float,float,float)
97 CBaseMonster::PlayScriptedSentence(char const *,float,float,float,int,CBaseEntity *)
98 CBaseMonster::SentenceStop(void)
99 CBaseMonster::GetIdealState(void)
100 CBaseMonster::SetActivity(Activity)
101 CBaseMonster::ReportAIState(void)
102 CBaseMonster::CheckEnemy(CBaseEntity *)
103 CBaseMonster::FTriangulate(Vector const &,Vector const &,float,CBaseEntity *,Vector *)
104 CBaseMonster::SetYawSpeed(void)
105 CBaseMonster::BuildNearestRoute(Vector,Vector ,float,float)
106 CBaseMonster::FindCover(Vector,Vector,float,f loat)
107 CBaseMonster::FValidateCover(Vector const &)
108 CBaseMonster::CoverRadius(void)
109 CBaseMonster::FCanCheckAttacks(void)
110 CBaseMonster::CheckAmmo(void)
111 CBaseMonster::IgnoreConditions(void)
112 CBaseMonster::FValidateHintType(short)
113 CBaseMonster::FCanActiveIdle(void)
114 CBaseMonster::ISoundMask(void)
115 CBaseMonster::PBestSound(void)
116 CBaseMonster::PBestScent(void)
117 CBaseMonster::HearingSensitivity(void)
118 CBasePlayer::BarnacleVictimBitten(entvars_s *)
119 CBasePlayer::BarnacleVictimReleased(void)
120 CBaseMonster::PrescheduleThink(void)
121 CBaseMonster::GetDeathActivity(void)
122 CBaseMonster::GibMonster(void)
123 CBaseMonster::HasHumanGibs(void)
124 CBaseMonster::HasAlienGibs(void)
125 CBaseMonster::FadeMonster(void)
126 CBaseMonster::RadiusDamage(entvars_s *,entvars_s *,float,int,int)
127 CBaseMonster::RadiusDamage(Vector,entvars_s *,entvars_s *,float,int,int)
128 CBasePlayer::DeathSound(void)
129 CBaseMonster::AlertSound(void)
130 CBaseMonster::IdleSound(void)
131 CBasePlayer::PainSound(void)
132 CBaseMonster::StopFollowing(int)
133 CBasePlayer::Jump(void)
134 CBasePlayer::Duck(void)
135 CBasePlayer::PreThink(void)
136 CBasePlayer::PostThink(void)
137 CBasePlayer::ImpulseCommands(void)

hlstriker
04-08-2011, 16:25
Thanks, I now understand how to find functions and structure members :) How would I find class members such as m_iTeamIndex though? I looked through IDA and the decompiled code and couldn't find member variables at all.

Arkshine
04-08-2011, 17:17
I have started to do a tutorial about that but since I want to be complete it needs some time (also things i still don't understand), anyway, it's the same way, pointer of class + offset.

Ex : m_iTeamIndex, label created by me (there is no reference, but you can guess what does the offset), you see : *(pPlayer + 308) . pPlayer being a pointer to CBasePlayer class. The data type seems to be an int, so the size is 4 bytes, then you do 308/4 = 77 for linux, 72 for windows (You need to remove -5 for windows and reversely for the CBasePlayer class, for weapon, it's generally +4 for linux).

You get the idea.

hlstriker
04-09-2011, 16:52
Alright awesome, looking forward to that tutorial :D

Bugsy
08-30-2011, 12:54
I am, for the first time, experimenting with orpheu and I'm having a hard time understanding how to make sense of the windows binaries. I open in IDA and have viewed the decompiled C-like code (ctrl F5?) but cannot locate specific functions. I tried to search by a string that is handled in the function but no strings appear in my decompiled code like it does in quims OP. The only way to view strings is in the strings window in IDA but I don't know how to link them with a particular function. When I view the linux library, everything is nice and each function carries its proper name and strings are in place in the code. Can anyone give me pointers? Do I have IDA configured incorrectly? My version is 6. something, paid edition.

Arkshine
08-30-2011, 14:29
That's why you have to work with both windows and linux at the same time, because on windows there is no symbols name like in linux. To find a function under windows, you have to find string or refs first on linux for a function, then you do the same for windows. Once the function found, rename it. You should rename as much you can. At first it's a pain but once you are used to do that, it's fairly fast.

Bugsy
08-30-2011, 14:41
But the problem is I cannot find any strings in the windows file, only linux. I decompile each to the c code and linux has strings throughout but windows has no strings. I did exactly as quim says in his OP but my windows.c file has no strings in it but my linux.c does...As explained in my post.

Arkshine
08-30-2011, 14:56
Decompiling helps more to see if the function is or less the same.

To find a function, you should search by string using the String Sub-view.

Menu : View > Open subviews -> Strings

Then, find your strings in the list ( Alt + T ), double-click, and you should see at the right of the string, where it's referenced. You may have more than one functions, and to see all functions, you can select the symbol of the string, click right and "Jump to xref to operand..." or directly X key.

Example :
77 65 61 70 6F 6E 73 2F 70 32+ aWeaponsP2281_w db 'weapons/p228-1.wav',0
.data:101063A0 32 38 2D 31 2E 77 61 76 00 ; DATA XREF: sub_1000BFF0+24o

You see at the right "sub_1000BFF0", it's function where the string is referenced and you can double-click on it. If you see there are more, select "aWeaponsP2281_w" and type X, you should see a windows with all the functions.

It's possible to use too the search function : Search > text...and with "Find all references" ticked.

Bugsy
08-30-2011, 15:14
Thanks for the info, I'll make another attempt when I get behind my pc tonight. Is there any reason why strings do not appear in my windows decompile .c file like they do in quims example in his OP? Linux yes, windows no. ie, I can't find "exec game.cfg" as he shows.

Arkshine
08-30-2011, 15:18
No, it should. I'm using the 5.5 version and it works fine. I can't help since I don't know the latest version. (Though I wish to have it just to see if the decompiled code is better)

Bugsy
08-30-2011, 15:31
I can post the .c if you want to look.

Edit: File too large to post on boards :\

Arkshine
08-30-2011, 15:55
Why not, show me.

drekes
08-30-2011, 17:34
I had the same problem.
http://forums.alliedmods.net/showpost.php?p=1430967&postcount=22

The solution for me was using version 5.5

Arkshine
08-31-2011, 07:29
What function Bugsy ? Because just tried on IDA 6.1 and I see well the strings in the decompiled code. For sure sometimes fails to decompile properly. If you are looking for a function and you fail to find a way for windows, tell me.

Bugsy
08-31-2011, 07:42
What function Bugsy ? Because just tried on IDA 6.1 and I see well the strings in the decompiled code. For sure sometimes fails to decompile properly. If you are looking for a function and you fail to find a way for windows, tell me.

Nothing in particular at this point, I am just experimenting out of curiousity\boredom. I did what drekes did and got version 5.5 and problem solved. The version I was using, v6.1, does not decompile any strings in place, I tried with various libraries\files with no luck. I'm not sure if it is configured wrong or what but I will just continue to use 5.5 for this purpose.

Reading about how to make signatures now.

Arkshine
08-31-2011, 08:20
Weird. I've configured nothing. Just opened the .dll and that's all.

Step1 : http://img824.**************/img824/1429/screenshot2011083114130.png
Step2 : http://img405.**************/img405/4690/screenshot2011083114143.png
Step3 : http://img684.**************/img684/4617/screenshot2011083114173.png
Step4 : http://img830.**************/img830/1329/screenshot2011083114175.png

:p

Bugsy
08-31-2011, 08:55
I didn't touch any settings and the strings do not get decompiled. Either they did away with that feature or it needs to be configured manually. Either of the two I do not agree with their decision.

HamletEagle
08-17-2014, 08:00
I have problems in decompiling mp.dll I got this error when pressing F5: "Decompilation Failure: call analysis failed" and I can't find InstallGameRules fuction( in cs.so everything is fine ). Someone know a solution ?

Edit: I found something but it's very different from the quim one:


int __cdecl sub_100810C0()
{
double v2; // st7@1
int v3; // eax@2
int v5; // eax@4
int v6; // esi@3

dword_10160C3C("exec game.cfg\n");
dword_10160C40();
v2 = *(float *)(LODWORD(dword_10160E18) + 20);
if ( v2 == 0.0 )
{
v3 = (int)operator new(0x2E8u);
if ( v3 )
{
v6 = v3;
sub_1008BCF0(v3, v2);
*(_DWORD *)v6 = off_100FD804;
dword_10160BA0("models/w_weaponbox.mdl");
return v6;
}
}
else
{
v5 = (int)operator new(0x2D0u);
if ( v5 )
return sub_1008BCF0(v5, v2);
}
return 0;
}

Bos93
08-17-2014, 09:05
Edit: I found something but it's very different from the quim one:

Build from 02-15-10 :)

HamletEagle
08-17-2014, 09:20
Build from 02-15-10 :)

Omg, you are right :fox:

addicted2sex
12-21-2016, 16:02
Can someone repost the pictures from the first post ?

klippy
12-21-2016, 16:25
Unless someone saved them (which is really unlikely), there's no way. ImageShack made a dick move where they removed all old images at one point, and even worse, made them into advertisements. Forums were full of ImageShack ads lol.

addicted2sex
12-22-2016, 14:19
So can someone tell me what the options have to be for both windows and linux libraries when importing them into IDA ?

klippy
12-22-2016, 14:37
Just clicking Next (or whatever to progress) through those dialogs will yield valid results. Maybe someone has something to recommend, but default settings work just fine.

DjSoftero
10-12-2017, 02:40
May anyone repost pictures? I mean someone who understands this stuff knows what should be where